Patchwork [2,of,7] ancestors: ensure a consistent order even in the "inclusive" case

login
register
mail settings
Submitter Boris Feld
Date Sept. 7, 2018, 3:04 p.m.
Message ID <9a18509c522deeb62a7b.1536332646@localhost.localdomain>
Download mbox | patch
Permalink /patch/34392/
State Accepted
Headers show

Comments

Boris Feld - Sept. 7, 2018, 3:04 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1536277058 14400
#      Thu Sep 06 19:37:38 2018 -0400
# Node ID 9a18509c522deeb62a7b244dcf4c7b79a8dc1132
# Parent  eb80c721aea9715e23dc35cdd119428aa120ea93
# EXP-Topic issue5979
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 9a18509c522d
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.
via Mercurial-devel - Sept. 7, 2018, 9:49 p.m.
On Fri, Sep 7, 2018 at 8:06 AM Boris Feld <boris.feld@octobus.net> wrote:

> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1536277058 14400
> #      Thu Sep 06 19:37:38 2018 -0400
> # Node ID 9a18509c522deeb62a7b244dcf4c7b79a8dc1132
> # Parent  eb80c721aea9715e23dc35cdd119428aa120ea93
> # EXP-Topic issue5979
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r
> 9a18509c522d
> ancestors: ensure a consistent order even in the "inclusive" case
>

I've queued the first two to start with. Thanks!

Patch

diff --git a/mercurial/ancestor.py b/mercurial/ancestor.py
--- a/mercurial/ancestor.py
+++ b/mercurial/ancestor.py
@@ -309,31 +309,30 @@  class lazyancestors(object):
         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)
diff --git a/tests/test-ancestor.py.out b/tests/test-ancestor.py.out
--- a/tests/test-ancestor.py.out
+++ b/tests/test-ancestor.py.out
@@ -9,10 +9,10 @@  membership: [1, 0]
 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]
diff --git a/tests/test-revlog-ancestry.py.out b/tests/test-revlog-ancestry.py.out
--- a/tests/test-revlog-ancestry.py.out
+++ b/tests/test-revlog-ancestry.py.out
@@ -9,7 +9,7 @@  6
 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