changeset 39474:a60dae060bc8

ancestors: ensure a consistent order even in the "inclusive" case It seems odds to first issue the "source" revs and then the other ancestors. In addition, doing so can break the other contract of always issuing a child before its parent. We update the code to apply the same logic to all yielded revision. No tests break so we seem in the clear except where we explicitly test the order.
author Boris Feld <boris.feld@octobus.net>
date Thu, 06 Sep 2018 19:37:38 -0400
parents b6db2e80a9ce
children 431068d7e9db
files mercurial/ancestor.py tests/test-ancestor.py.out tests/test-revlog-ancestry.py.out
diffstat 3 files changed, 17 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/ancestor.py	Thu Sep 06 17:00:28 2018 -0400
+++ b/mercurial/ancestor.py	Thu Sep 06 19:37:38 2018 -0400
@@ -309,31 +309,30 @@
         revision number order. That order is also topological: a child is
         always emitted before its parent.
 
-        If inclusive is True, yield all the revs first (ignoring stoprev),
-        then yield all the ancestors of revs as when inclusive is False. If an
-        element in revs is an ancestor of a different rev it is not yielded
-        again."""
+        If inclusive is True, the source revisions are also yielded. The
+        reverse revision number order is still enforced."""
         seen = set()
         revs = self._initrevs
-        if self._inclusive:
-            for rev in revs:
-                yield rev
-            seen.update(revs)
 
         parentrevs = self._parentrevs
         stoprev = self._stoprev
-        visit = []
-        heapq.heapify(visit)
         schedule = heapq.heappush
         nextitem = heapq.heappop
         see = seen.add
         see(nullrev)
 
-        for r in revs:
-            for parent in parentrevs(r):
-                if parent not in seen:
-                    schedule(visit, -parent)
-                    see(parent)
+        if self._inclusive:
+            visit = [-r for r in revs]
+            seen.update(revs)
+            heapq.heapify(visit)
+        else:
+            visit = []
+            heapq.heapify(visit)
+            for r in revs:
+                for parent in parentrevs(r):
+                    if parent not in seen:
+                        schedule(visit, -parent)
+                        see(parent)
 
         while visit:
             current = -nextitem(visit)
--- a/tests/test-ancestor.py.out	Thu Sep 06 17:00:28 2018 -0400
+++ b/tests/test-ancestor.py.out	Thu Sep 06 19:37:38 2018 -0400
@@ -9,10 +9,10 @@
 iteration:  [1, 0]
 % lazy ancestor set for [11, 13], stoprev = 0, inclusive = True
 membership: [11, 13, 7, 8, 3, 4, 1, 0]
-iteration:  [11, 13, 8, 7, 4, 3, 2, 1, 0]
+iteration:  [13, 11, 8, 7, 4, 3, 2, 1, 0]
 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = False
 membership: [7, 8]
 iteration:  [8, 7]
 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = True
 membership: [11, 13, 7, 8]
-iteration:  [11, 13, 8, 7]
+iteration:  [13, 11, 8, 7]
--- a/tests/test-revlog-ancestry.py.out	Thu Sep 06 17:00:28 2018 -0400
+++ b/tests/test-revlog-ancestry.py.out	Thu Sep 06 19:37:38 2018 -0400
@@ -9,7 +9,7 @@
 Ancestors of 7, including revs
 7 6 5 4 3 2 1 0 
 Ancestors of 7, 5 and 3, including revs
-7 5 3 6 4 2 1 0 
+7 6 5 4 3 2 1 0 
 
 Descendants of 5
 7 8