##// END OF EJS Templates
ancestors: actually iterate over ancestors in topological order (issue5979)...
Boris Feld -
r39509:b6db2e80 default
parent child Browse files
Show More
@@ -0,0 +1,34 b''
1 $ hg init r1
2 $ cd r1
3 $ hg ci --config ui.allowemptycommit=true -m c0
4 $ hg ci --config ui.allowemptycommit=true -m c1
5 $ hg ci --config ui.allowemptycommit=true -m c2
6 $ hg co -q 0
7 $ hg ci --config ui.allowemptycommit=true -m c3
8 created new head
9 $ hg co -q 3
10 $ hg merge --quiet
11 $ hg ci --config ui.allowemptycommit=true -m c4
12
13 $ hg log -G -T'{desc}'
14 @ c4
15 |\
16 | o c3
17 | |
18 o | c2
19 | |
20 o | c1
21 |/
22 o c0
23
24
25 >>> from mercurial.ui import ui
26 >>> from mercurial.hg import repository
27 >>> repo = repository(ui())
28 >>> for anc in repo.changelog.ancestors([4], inclusive=True):
29 ... print(anc)
30 4
31 3
32 2
33 1
34 0
@@ -7,7 +7,6 b''
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import collections
11 import heapq
10 import heapq
12
11
13 from .node import nullrev
12 from .node import nullrev
@@ -305,14 +304,15 b' class lazyancestors(object):'
305 """Generate the ancestors of _initrevs in reverse topological order.
304 """Generate the ancestors of _initrevs in reverse topological order.
306
305
307 If inclusive is False, yield a sequence of revision numbers starting
306 If inclusive is False, yield a sequence of revision numbers starting
308 with the parents of each revision in revs, i.e., each revision is *not*
307 with the parents of each revision in revs, i.e., each revision is
309 considered an ancestor of itself. Results are in breadth-first order:
308 *not* considered an ancestor of itself. Results are emitted in reverse
310 parents of each rev in revs, then parents of those, etc.
309 revision number order. That order is also topological: a child is
310 always emitted before its parent.
311
311
312 If inclusive is True, yield all the revs first (ignoring stoprev),
312 If inclusive is True, yield all the revs first (ignoring stoprev),
313 then yield all the ancestors of revs as when inclusive is False.
313 then yield all the ancestors of revs as when inclusive is False. If an
314 If an element in revs is an ancestor of a different rev it is not
314 element in revs is an ancestor of a different rev it is not yielded
315 yielded again."""
315 again."""
316 seen = set()
316 seen = set()
317 revs = self._initrevs
317 revs = self._initrevs
318 if self._inclusive:
318 if self._inclusive:
@@ -322,17 +322,27 b' class lazyancestors(object):'
322
322
323 parentrevs = self._parentrevs
323 parentrevs = self._parentrevs
324 stoprev = self._stoprev
324 stoprev = self._stoprev
325 visit = collections.deque(revs)
325 visit = []
326 heapq.heapify(visit)
327 schedule = heapq.heappush
328 nextitem = heapq.heappop
329 see = seen.add
330 see(nullrev)
326
331
327 see = seen.add
332 for r in revs:
328 schedule = visit.append
333 for parent in parentrevs(r):
334 if parent not in seen:
335 schedule(visit, -parent)
336 see(parent)
329
337
330 while visit:
338 while visit:
331 for parent in parentrevs(visit.popleft()):
339 current = -nextitem(visit)
332 if parent >= stoprev and parent not in seen:
340 if current >= stoprev:
333 schedule(parent)
341 yield current
342 for parent in parentrevs(current):
343 if parent not in seen:
344 schedule(visit, -parent)
334 see(parent)
345 see(parent)
335 yield parent
336
346
337 def __contains__(self, target):
347 def __contains__(self, target):
338 """Test whether target is an ancestor of self._initrevs."""
348 """Test whether target is an ancestor of self._initrevs."""
@@ -3,16 +3,16 b' membership: []'
3 iteration: []
3 iteration: []
4 % lazy ancestor set for [11, 13], stoprev = 0, inclusive = False
4 % lazy ancestor set for [11, 13], stoprev = 0, inclusive = False
5 membership: [7, 8, 3, 4, 1, 0]
5 membership: [7, 8, 3, 4, 1, 0]
6 iteration: [3, 7, 8, 1, 4, 0, 2]
6 iteration: [8, 7, 4, 3, 2, 1, 0]
7 % lazy ancestor set for [1, 3], stoprev = 0, inclusive = False
7 % lazy ancestor set for [1, 3], stoprev = 0, inclusive = False
8 membership: [1, 0]
8 membership: [1, 0]
9 iteration: [0, 1]
9 iteration: [1, 0]
10 % lazy ancestor set for [11, 13], stoprev = 0, inclusive = True
10 % lazy ancestor set for [11, 13], stoprev = 0, inclusive = True
11 membership: [11, 13, 7, 8, 3, 4, 1, 0]
11 membership: [11, 13, 7, 8, 3, 4, 1, 0]
12 iteration: [11, 13, 3, 7, 8, 1, 4, 0, 2]
12 iteration: [11, 13, 8, 7, 4, 3, 2, 1, 0]
13 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = False
13 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = False
14 membership: [7, 8]
14 membership: [7, 8]
15 iteration: [7, 8]
15 iteration: [8, 7]
16 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = True
16 % lazy ancestor set for [11, 13], stoprev = 6, inclusive = True
17 membership: [11, 13, 7, 8]
17 membership: [11, 13, 7, 8]
18 iteration: [11, 13, 7, 8]
18 iteration: [11, 13, 8, 7]
@@ -1,13 +1,13 b''
1 Ancestors of 5
1 Ancestors of 5
2 4 2 0
2 4 2 0
3 Ancestors of 6 and 5
3 Ancestors of 6 and 5
4 3 4 2 1 0
4 4 3 2 1 0
5 Ancestors of 5 and 4
5 Ancestors of 5 and 4
6 4 2 0
6 4 2 0
7 Ancestors of 7, stop at 6
7 Ancestors of 7, stop at 6
8 6
8 6
9 Ancestors of 7, including revs
9 Ancestors of 7, including revs
10 7 6 5 3 4 2 1 0
10 7 6 5 4 3 2 1 0
11 Ancestors of 7, 5 and 3, including revs
11 Ancestors of 7, 5 and 3, including revs
12 7 5 3 6 4 2 1 0
12 7 5 3 6 4 2 1 0
13
13
General Comments 0
You need to be logged in to leave comments. Login now