# HG changeset patch # User Bryan O'Sullivan # Date 1203543496 28800 # Node ID 8bc4fe428103ab2b5a332b9c92589247b7f455e5 # Parent aafdea37f7968088508ea53cfc53a79625655e7b# Parent b023915aa1bc5980e7048c36ad74c8520d220864 Merge with crew diff -r aafdea37f796 -r 8bc4fe428103 mercurial/cmdutil.py --- 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') diff -r aafdea37f796 -r 8bc4fe428103 mercurial/commands.py --- 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() diff -r aafdea37f796 -r 8bc4fe428103 mercurial/hgweb/hgweb_mod.py --- 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) diff -r aafdea37f796 -r 8bc4fe428103 mercurial/repair.py --- 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) diff -r aafdea37f796 -r 8bc4fe428103 mercurial/revlog.py --- 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)] diff -r aafdea37f796 -r 8bc4fe428103 tests/test-convert.out --- 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