# HG changeset patch # User Matt Mackall # Date 1416697744 21600 # Node ID a81c76106d9036060b3371f36b00ceefa5d60898 # Parent 90cc552ceed50517508bde816b88d0d47e60bce1# Parent cc0ff93d0c0c29526465a1d07b9eddf5b2da51dd merge with stable diff -r 90cc552ceed5 -r a81c76106d90 mercurial/changegroup.py --- a/mercurial/changegroup.py Thu Nov 20 16:39:32 2014 -0800 +++ b/mercurial/changegroup.py Sat Nov 22 17:09:04 2014 -0600 @@ -325,6 +325,7 @@ # for progress output msgbundling = _('bundling') + clrevorder = {} mfs = {} # needed manifests fnodes = {} # needed file nodes changedfiles = set() @@ -334,6 +335,7 @@ # Returns the linkrev node (identity in the changelog case). def lookupcl(x): c = cl.read(x) + clrevorder[x] = len(clrevorder) changedfiles.update(c[3]) # record the first changeset introducing this manifest version mfs.setdefault(c[0], x) @@ -349,13 +351,16 @@ # Returns the linkrev node (collected in lookupcl). def lookupmf(x): clnode = mfs[x] - if not fastpathlinkrev: + if not fastpathlinkrev or reorder: mdata = mf.readfast(x) for f, n in mdata.iteritems(): if f in changedfiles: # record the first changeset introducing this filelog # version - fnodes.setdefault(f, {}).setdefault(n, clnode) + fclnodes = fnodes.setdefault(f, {}) + fclnode = fclnodes.setdefault(n, clnode) + if clrevorder[clnode] < clrevorder[fclnode]: + fclnodes[n] = clnode return clnode mfnodes = self.prune(mf, mfs, commonrevs, source) @@ -368,7 +373,7 @@ needed = set(cl.rev(x) for x in clnodes) def linknodes(filerevlog, fname): - if fastpathlinkrev: + if fastpathlinkrev and not reorder: llr = filerevlog.linkrev def genfilenodes(): for r in filerevlog: diff -r 90cc552ceed5 -r a81c76106d90 mercurial/exchange.py --- a/mercurial/exchange.py Thu Nov 20 16:39:32 2014 -0800 +++ b/mercurial/exchange.py Sat Nov 22 17:09:04 2014 -0600 @@ -681,51 +681,15 @@ # filter heads already turned public by the push outdated = [c for c in outdated if c.node() not in pheads] - b2caps = bundle2.bundle2caps(pushop.remote) - if 'b2x:pushkey' in b2caps: - # server supports bundle2, let's do a batched push through it - # - # This will eventually be unified with the changesets bundle2 push - bundler = bundle2.bundle20(pushop.ui, b2caps) - capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo)) - bundler.newpart('b2x:replycaps', data=capsblob) - part2node = [] - enc = pushkey.encode - for newremotehead in outdated: - part = bundler.newpart('b2x:pushkey') - part.addparam('namespace', enc('phases')) - part.addparam('key', enc(newremotehead.hex())) - part.addparam('old', enc(str(phases.draft))) - part.addparam('new', enc(str(phases.public))) - part2node.append((part.id, newremotehead)) - stream = util.chunkbuffer(bundler.getchunks()) - try: - reply = pushop.remote.unbundle(stream, ['force'], 'push') - op = bundle2.processbundle(pushop.repo, reply) - except error.BundleValueError, exc: - raise util.Abort('missing support for %s' % exc) - for partid, node in part2node: - partrep = op.records.getreplies(partid) - results = partrep['pushkey'] - assert len(results) <= 1 - msg = None - if not results: - msg = _('server ignored update of %s to public!\n') % node - elif not int(results[0]['return']): - msg = _('updating %s to public failed!\n') % node - if msg is not None: - pushop.ui.warn(msg) - - else: - # fallback to independent pushkey command - for newremotehead in outdated: - r = pushop.remote.pushkey('phases', - newremotehead.hex(), - str(phases.draft), - str(phases.public)) - if not r: - pushop.ui.warn(_('updating %s to public failed!\n') - % newremotehead) + # fallback to independent pushkey command + for newremotehead in outdated: + r = pushop.remote.pushkey('phases', + newremotehead.hex(), + str(phases.draft), + str(phases.public)) + if not r: + pushop.ui.warn(_('updating %s to public failed!\n') + % newremotehead) def _localphasemove(pushop, nodes, phase=phases.public): """move to in the local source repo""" diff -r 90cc552ceed5 -r a81c76106d90 mercurial/templates/paper/search.tmpl --- a/mercurial/templates/paper/search.tmpl Thu Nov 20 16:39:32 2014 -0800 +++ b/mercurial/templates/paper/search.tmpl Sat Nov 22 17:09:04 2014 -0600 @@ -38,8 +38,8 @@ @@ -54,8 +54,8 @@
diff -r 90cc552ceed5 -r a81c76106d90 tests/test-generaldelta.t --- a/tests/test-generaldelta.t Thu Nov 20 16:39:32 2014 -0800 +++ b/tests/test-generaldelta.t Sat Nov 22 17:09:04 2014 -0600 @@ -22,3 +22,50 @@ >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size >>> if regsize < gdsize: ... print 'generaldata increased size of manifest' + +Verify rev reordering doesnt create invalid bundles (issue4462) +This requires a commit tree that when pulled will reorder manifest revs such +that the second manifest to create a file rev will be ordered before the first +manifest to create that file rev. We also need to do a partial pull to ensure +reordering happens. At the end we verify the linkrev points at the earliest +commit. + + $ hg init server --config format.generaldelta=True + $ cd server + $ touch a + $ hg commit -Aqm a + $ echo x > x + $ echo y > y + $ hg commit -Aqm xy + $ hg up -q '.^' + $ echo x > x + $ echo z > z + $ hg commit -Aqm xz + $ hg up -q 1 + $ echo b > b + $ hg commit -Aqm b + $ hg merge -q 2 + $ hg commit -Aqm merge + $ echo c > c + $ hg commit -Aqm c + $ hg log -G -T '{rev} {shortest(node)} {desc}' + @ 5 ebb8 c + | + o 4 baf7 merge + |\ + | o 3 a129 b + | | + o | 2 958c xz + | | + | o 1 f00c xy + |/ + o 0 3903 a + + $ cd .. + $ hg init client + $ cd client + $ hg pull -q ../server -r 4 + $ hg debugindex x + rev offset length base linkrev nodeid p1 p2 + 0 0 3 0 1 1406e7411862 000000000000 000000000000 + diff -r 90cc552ceed5 -r a81c76106d90 tests/test-hgweb-commands.t --- a/tests/test-hgweb-commands.t Thu Nov 20 16:39:32 2014 -0800 +++ b/tests/test-hgweb-commands.t Sat Nov 22 17:09:04 2014 -0600 @@ -1007,8 +1007,8 @@ @@ -1028,8 +1028,8 @@