changegroup: fix treemanifest exchange code (issue5061) stable
authorAugie Fackler <augie@google.com>
Wed, 27 Jan 2016 10:24:25 -0500
branchstable
changeset 29895 ca8d2b73155d30d7402391cb48ab6727cd33f9e7
parent 29894 4186d359046a87aa303132894dec49bbfb1fd87f
child 29896 571ba161f6be9ad696efcdbcf8bdf0a8a6ba0766
push id175
push usergszorc@mozilla.com
push dateWed, 10 Feb 2016 01:24:28 +0000
changegroup: fix treemanifest exchange code (issue5061) There were two mistakes: one was accidental reuse of the fclnode variable from the loop gathering file nodes, and the other (masked by that bug) was not correctly handling deleted directories. Both cases are now fixed and the test passes.
mercurial/changegroup.py
tests/test-treemanifest.t
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -773,22 +773,25 @@ class cg1packer(object):
                     fclnodes = fnodes.setdefault(f, {})
                     fclnode = fclnodes.setdefault(n, clnode)
                     if clrevorder[clnode] < clrevorder[fclnode]:
                         fclnodes[n] = clnode
                 # gather list of changed treemanifest nodes
                 if 'treemanifest' in repo.requirements:
                     submfs = {'/': mdata}
                     for dn, bn in _moddirs(mfchangedfiles[x]):
-                        submf = submfs[dn]
-                        submf = submf._dirs[bn]
+                        try:
+                            submf = submfs[dn]
+                            submf = submf._dirs[bn]
+                        except KeyError:
+                            continue # deleted directory, so nothing to send
                         submfs[submf.dir()] = submf
                         tmfclnodes = tmfnodes.setdefault(submf.dir(), {})
-                        tmfclnodes.setdefault(submf._node, clnode)
-                        if clrevorder[clnode] < clrevorder[fclnode]:
+                        tmfclnode = tmfclnodes.setdefault(submf._node, clnode)
+                        if clrevorder[clnode] < clrevorder[tmfclnode]:
                             tmfclnodes[n] = clnode
                 return clnode
 
         mfnodes = self.prune(ml, mfs, commonrevs)
         for x in self._packmanifests(
             mfnodes, tmfnodes, lookupmflinknode):
             yield x
 
--- a/tests/test-treemanifest.t
+++ b/tests/test-treemanifest.t
@@ -327,16 +327,31 @@ Pushing from treemanifest repo to an emp
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 2 changes to 2 files
   $ grep treemanifest empty-repo/.hg/requires
   treemanifest
 
+Pushing to an empty repo works
+
+  $ hg --config experimental.treemanifest=1 init clone
+  $ grep treemanifest clone/.hg/requires
+  treemanifest
+  $ hg push -R repo clone
+  pushing to clone
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 11 changesets with 15 changes to 10 files (+3 heads)
+  $ grep treemanifest clone/.hg/requires
+  treemanifest
+
 Create deeper repo with tree manifests.
 
   $ hg --config experimental.treemanifest=True init deeprepo
   $ cd deeprepo
 
   $ mkdir a
   $ mkdir b
   $ mkdir b/bar