revlog.ancestors: add support for including revs
This is in preparation for an upcoming refactoring. This also fixes a bug in
incancestors, where if an element of revs was an ancestor of another it would
be generated twice.
--- a/mercurial/revlog.py Fri Dec 14 10:23:18 2012 -0800
+++ b/mercurial/revlog.py Mon Dec 17 15:13:51 2012 -0800
@@ -341,17 +341,27 @@
return len(t)
size = rawsize
- def ancestors(self, revs, stoprev=0):
+ def ancestors(self, revs, stoprev=0, inclusive=False):
"""Generate the ancestors of 'revs' in reverse topological order.
Does not generate revs lower than stoprev.
- Yield a sequence of revision numbers starting with the parents
- of each revision in revs, i.e., each revision is *not* considered
- an ancestor of itself. Results are in breadth-first order:
- parents of each rev in revs, then parents of those, etc. Result
- does not include the null revision."""
+ If inclusive is False, yield a sequence of revision numbers starting
+ with the parents of each revision in revs, i.e., each revision is *not*
+ considered an ancestor of itself. Results are in breadth-first order:
+ parents of each rev in revs, then parents of those, etc.
+
+ 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.
+
+ Result does not include the null revision."""
visit = util.deque(revs)
seen = set([nullrev])
+ if inclusive:
+ for rev in revs:
+ yield rev
+ seen.update(revs)
while visit:
for parent in self.parentrevs(visit.popleft()):
if parent < stoprev:
@@ -364,10 +374,7 @@
def incancestors(self, revs, stoprev=0):
"""Identical to ancestors() except it also generates the
revisions, 'revs'"""
- for rev in revs:
- yield rev
- for rev in self.ancestors(revs, stoprev):
- yield rev
+ return self.ancestors(revs, stoprev, inclusive=True)
def descendants(self, revs):
"""Generate the descendants of 'revs' in revision order.
--- a/tests/test-revlog-ancestry.py Fri Dec 14 10:23:18 2012 -0800
+++ b/tests/test-revlog-ancestry.py Mon Dec 17 15:13:51 2012 -0800
@@ -62,6 +62,14 @@
for r in repo.changelog.ancestors([7], 6):
print r,
+ print '\nAncestors of 7, including revs'
+ for r in repo.changelog.ancestors([7], inclusive=True):
+ print r,
+
+ print '\nAncestors of 7, 5 and 3, including revs'
+ for r in repo.changelog.ancestors([7, 5, 3], inclusive=True):
+ print r,
+
# Descendants
print '\n\nDescendants of 5'
for r in repo.changelog.descendants([5]):
--- a/tests/test-revlog-ancestry.py.out Fri Dec 14 10:23:18 2012 -0800
+++ b/tests/test-revlog-ancestry.py.out Mon Dec 17 15:13:51 2012 -0800
@@ -6,6 +6,10 @@
4 2 0
Ancestors of 7, stop at 6
6
+Ancestors of 7, including revs
+7 6 5 3 4 2 1 0
+Ancestors of 7, 5 and 3, including revs
+7 5 3 6 4 2 1 0
Descendants of 5
7 8