pullbundle: improves management of multiple branch while dealing with a head
authorPierre-Yves David <pierre-yves.david@octobus.net>
Wed, 26 Sep 2018 18:41:55 +0200
changeset 4148 5ef93dbace5e
parent 4147 88e922eca4e2
child 4149 4abec3a1208f
pullbundle: improves management of multiple branch while dealing with a head There were still case where a range was issued too early.
hgext3rd/pullbundle.py
--- a/hgext3rd/pullbundle.py	Wed Sep 26 18:42:44 2018 +0200
+++ b/hgext3rd/pullbundle.py	Wed Sep 26 18:41:55 2018 +0200
@@ -176,6 +176,8 @@
 
 # stable range slicing
 
+DEBUG = False
+
 def sliceoutgoing(repo, outgoing):
     cl = repo.changelog
     rev = cl.nodemap.get
@@ -183,23 +185,51 @@
     revsort = repo.stablesort
 
     missingrevs = set(rev(n) for n in outgoing.missing)
+    if DEBUG:
+        ms = missingrevs.copy()
+        ss = []
     allslices = []
     missingheads = [rev(n) for n in sorted(outgoing.missingheads, reverse=True)]
     for head in missingheads:
         localslices = []
         localmissing = set(repo.revs('%ld and ::%d', missingrevs, head))
+        thisrunmissing =  localmissing.copy()
         while localmissing:
             slicerevs = []
             for r in revsort.walkfrom(repo, head):
-                if r not in missingrevs:
+                if r not in thisrunmissing:
                     break
                 slicerevs.append(r)
             slicenodes = [node(r) for r in slicerevs]
             localslices.append(canonicalslices(repo, slicenodes))
+            if DEBUG:
+                ss.append(slicerevs)
             missingrevs.difference_update(slicerevs)
             localmissing.difference_update(slicerevs)
             if localmissing:
-                head = max(localmissing)
+                heads = list(repo.revs('heads(%ld)', localmissing))
+                heads.sort(key=node)
+                head = heads.pop()
+                if heads:
+                    thisrunmissing = repo.revs('%ld and only(%d, %ld)',
+                                               localmissing,
+                                               head,
+                                               heads)
+                else:
+                    thisrunmissing = localmissing.copy()
+        if DEBUG:
+            for s in reversed(ss):
+                ms -= set(s)
+                missingbase = repo.revs('parents(%ld) and %ld', s, ms)
+                if missingbase:
+                    repo.ui.write_err('!!! rev bundled while parents missing\n')
+                    repo.ui.write_err('    parent: %s\n' % list(missingbase))
+                    pb = repo.revs('%ld and children(%ld)', s, missingbase)
+                    repo.ui.write_err('    children: %s\n' % list(pb))
+                    h = repo.revs('heads(%ld)', s)
+                    repo.ui.write_err('    heads: %s\n' % list(h))
+                    raise error.ProgrammingError('issuing a range before its parents')
+
         for s in reversed(localslices):
             allslices.extend(s)
     # unknown subrange might had to be computed