--- a/mercurial/cmdutil.py Fri Jan 25 04:11:32 2008 -0500
+++ b/mercurial/cmdutil.py Wed Feb 20 13:38:16 2008 -0800
@@ -967,7 +967,7 @@
if follow:
defrange = '%s:0' % repo.changectx().rev()
else:
- defrange = 'tip:0'
+ defrange = '-1:0'
revs = revrange(repo, opts['rev'] or [defrange])
wanted = {}
slowpath = anypats or opts.get('removed')
--- a/mercurial/commands.py Fri Jan 25 04:11:32 2008 -0500
+++ b/mercurial/commands.py Wed Feb 20 13:38:16 2008 -0800
@@ -1072,19 +1072,19 @@
if st == 'window':
matches.clear()
elif st == 'add':
- mf = repo.changectx(rev).manifest()
+ ctx = repo.changectx(rev)
matches[rev] = {}
for fn in fns:
if fn in skip:
continue
try:
- grepbody(fn, rev, getfile(fn).read(mf[fn]))
+ grepbody(fn, rev, getfile(fn).read(ctx.filenode(fn)))
fstate.setdefault(fn, [])
if follow:
- copied = getfile(fn).renamed(mf[fn])
+ copied = getfile(fn).renamed(ctx.filenode(fn))
if copied:
copies.setdefault(rev, {})[fn] = copied[0]
- except KeyError:
+ except revlog.LookupError:
pass
elif st == 'iter':
states = matches[rev].items()
--- a/mercurial/hgweb/hgweb_mod.py Fri Jan 25 04:11:32 2008 -0500
+++ b/mercurial/hgweb/hgweb_mod.py Wed Feb 20 13:38:16 2008 -0800
@@ -199,35 +199,38 @@
req.form['node'] = [fn[:-len(ext)]]
req.form['type'] = [type_]
- # actually process the request
+ # process this if it's a protocol request
+
+ cmd = req.form.get('cmd', [''])[0]
+ if cmd in protocol.__all__:
+ method = getattr(protocol, cmd)
+ method(self, req)
+ return
+
+ # process the web interface request
try:
- cmd = req.form.get('cmd', [''])[0]
- if cmd in protocol.__all__:
- method = getattr(protocol, cmd)
- method(self, req)
- else:
- tmpl = self.templater(req)
- ctype = tmpl('mimetype', encoding=self.encoding)
- ctype = templater.stringify(ctype)
-
- if cmd == '':
- req.form['cmd'] = [tmpl.cache['default']]
- cmd = req.form['cmd'][0]
+ tmpl = self.templater(req)
+ ctype = tmpl('mimetype', encoding=self.encoding)
+ ctype = templater.stringify(ctype)
+
+ if cmd == '':
+ req.form['cmd'] = [tmpl.cache['default']]
+ cmd = req.form['cmd'][0]
- if cmd not in webcommands.__all__:
- msg = 'No such method: %s' % cmd
- raise ErrorResponse(HTTP_BAD_REQUEST, msg)
- elif cmd == 'file' and 'raw' in req.form.get('style', []):
- self.ctype = ctype
- content = webcommands.rawfile(self, req, tmpl)
- else:
- content = getattr(webcommands, cmd)(self, req, tmpl)
- req.respond(HTTP_OK, ctype)
+ if cmd not in webcommands.__all__:
+ msg = 'No such method: %s' % cmd
+ raise ErrorResponse(HTTP_BAD_REQUEST, msg)
+ elif cmd == 'file' and 'raw' in req.form.get('style', []):
+ self.ctype = ctype
+ content = webcommands.rawfile(self, req, tmpl)
+ else:
+ content = getattr(webcommands, cmd)(self, req, tmpl)
+ req.respond(HTTP_OK, ctype)
- req.write(content)
- del tmpl
+ req.write(content)
+ del tmpl
except revlog.LookupError, err:
req.respond(HTTP_NOT_FOUND, ctype)
--- a/mercurial/repair.py Fri Jan 25 04:11:32 2008 -0500
+++ b/mercurial/repair.py Wed Feb 20 13:38:16 2008 -0800
@@ -9,18 +9,6 @@
import changegroup, os
from node import *
-def _limitheads(cl, stoprev):
- """return the list of all revs >= stoprev that have no children"""
- seen = {}
- heads = []
-
- for r in xrange(cl.count() - 1, stoprev - 1, -1):
- if r not in seen:
- heads.append(r)
- for p in cl.parentrevs(r):
- seen[p] = 1
- return heads
-
def _bundle(repo, bases, heads, node, suffix, extranodes=None):
"""create a bundle with the specified revisions as a backup"""
cg = repo.changegroupsubset(bases, heads, 'strip', extranodes)
@@ -87,42 +75,39 @@
pp = cl.parents(node)
striprev = cl.rev(node)
- # save is a list of all the branches we are truncating away
- # that we actually want to keep. changegroup will be used
- # to preserve them and add them back after the truncate
- saveheads = []
- savebases = {}
-
- heads = [cl.node(r) for r in _limitheads(cl, striprev)]
- seen = {}
+ # Some revisions with rev > striprev may not be descendants of striprev.
+ # We have to find these revisions and put them in a bundle, so that
+ # we can restore them after the truncations.
+ # To create the bundle we use repo.changegroupsubset which requires
+ # the list of heads and bases of the set of interesting revisions.
+ # (head = revision in the set that has no descendant in the set;
+ # base = revision in the set that has no ancestor in the set)
+ tostrip = {striprev: 1}
+ saveheads = {}
+ savebases = []
+ for r in xrange(striprev + 1, cl.count()):
+ parents = cl.parentrevs(r)
+ if parents[0] in tostrip or parents[1] in tostrip:
+ # r is a descendant of striprev
+ tostrip[r] = 1
+ # if this is a merge and one of the parents does not descend
+ # from striprev, mark that parent as a savehead.
+ if parents[1] != nullrev:
+ for p in parents:
+ if p not in tostrip and p > striprev:
+ saveheads[p] = 1
+ else:
+ # if no parents of this revision will be stripped, mark it as
+ # a savebase
+ if parents[0] < striprev and parents[1] < striprev:
+ savebases.append(cl.node(r))
- # search through all the heads, finding those where the revision
- # we want to strip away is an ancestor. Also look for merges
- # that might be turned into new heads by the strip.
- while heads:
- h = heads.pop()
- n = h
- while True:
- seen[n] = 1
- pp = cl.parents(n)
- if pp[1] != nullid:
- for p in pp:
- if cl.rev(p) > striprev and p not in seen:
- heads.append(p)
- if pp[0] == nullid:
- break
- if cl.rev(pp[0]) < striprev:
- break
- n = pp[0]
- if n == node:
- break
- r = cl.reachable(h, node)
- if node not in r:
- saveheads.append(h)
- for x in r:
- if cl.rev(x) > striprev:
- savebases[x] = 1
+ for p in parents:
+ if p in saveheads:
+ del saveheads[p]
+ saveheads[r] = 1
+ saveheads = [cl.node(r) for r in saveheads]
files = _collectfiles(repo, striprev)
extranodes = _collectextranodes(repo, files, striprev)
@@ -131,7 +116,7 @@
if backup == "all":
_bundle(repo, [node], cl.heads(), node, 'backup')
if saveheads or extranodes:
- chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp',
+ chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
extranodes)
cl.strip(striprev)
--- a/mercurial/revlog.py Fri Jan 25 04:11:32 2008 -0500
+++ b/mercurial/revlog.py Wed Feb 20 13:38:16 2008 -0800
@@ -933,19 +933,19 @@
raise RevlogError(_('incompatible revision flag %x') %
(self.index[rev][0] & 0xFFFF))
- if self._inline:
- # we probably have the whole chunk cached
- df = None
- else:
- df = self.opener(self.datafile)
+ df = None
# do we have useful data cached?
if self._cache and self._cache[1] >= base and self._cache[1] < rev:
base = self._cache[1]
text = str(self._cache[2])
self._loadindex(base, rev + 1)
+ if not self._inline and rev > base + 1:
+ df = self.opener(self.datafile)
else:
self._loadindex(base, rev + 1)
+ if not self._inline and rev > base:
+ df = self.opener(self.datafile)
text = self.chunk(base, df=df)
bins = [self.chunk(r, df) for r in xrange(base + 1, rev + 1)]
--- a/tests/test-convert.out Fri Jan 25 04:11:32 2008 -0500
+++ b/tests/test-convert.out Wed Feb 20 13:38:16 2008 -0800
@@ -56,6 +56,17 @@
subdirectory into the root of the repository, use '.' as the path to
rename to.
+ The splicemap is a file that allows insertion of synthetic
+ history, letting you specify the parents of a revision. This is
+ useful if you want to e.g. give a Subversion merge two parents, or
+ graft two disconnected series of history together. Each entry
+ contains a key, followed by a space, followed by one or two
+ values, separated by spaces. The key is the revision ID in the
+ source revision control system whose parents should be modified
+ (same format as a key in .hg/shamap). The values are the revision
+ IDs (in either the source or destination revision control system)
+ that should be used as the new parents for that node.
+
Back end options:
--config convert.hg.clonebranches=False (boolean)
@@ -81,6 +92,7 @@
--filemap remap file names using contents of file
-r --rev import up to target revision REV
-s --source-type source repository type
+ --splicemap splice synthesized history into place
--datesort try to sort changesets by date
use "hg -v help convert" to show global options