##// END OF EJS Templates
revset: add startdepth limit to ancestors() as internal option...
Yuya Nishihara -
r33003:f63d1112 default
parent child Browse files
Show More
@@ -23,11 +23,13 b' generatorset = smartset.generatorset'
23 # possible maximum depth between null and wdir()
23 # possible maximum depth between null and wdir()
24 _maxlogdepth = 0x80000000
24 _maxlogdepth = 0x80000000
25
25
26 def _genrevancestors(repo, revs, followfirst, stopdepth):
26 def _genrevancestors(repo, revs, followfirst, startdepth, stopdepth):
27 if followfirst:
27 if followfirst:
28 cut = 1
28 cut = 1
29 else:
29 else:
30 cut = None
30 cut = None
31 if startdepth is None:
32 startdepth = 0
31 if stopdepth is None:
33 if stopdepth is None:
32 stopdepth = _maxlogdepth
34 stopdepth = _maxlogdepth
33 if stopdepth <= 0:
35 if stopdepth <= 0:
@@ -53,8 +55,10 b' def _genrevancestors(repo, revs, followf'
53 inputrev = next(irevs, None)
55 inputrev = next(irevs, None)
54 if inputrev is not None:
56 if inputrev is not None:
55 heapq.heappush(pendingheap, (-inputrev, 0))
57 heapq.heappush(pendingheap, (-inputrev, 0))
58 # rescan parents until curdepth >= startdepth because queued entries
59 # of the same revision are iterated from the lowest depth
56 foundnew = (currev != lastrev)
60 foundnew = (currev != lastrev)
57 if foundnew:
61 if foundnew and curdepth >= startdepth:
58 lastrev = currev
62 lastrev = currev
59 yield currev
63 yield currev
60 pdepth = curdepth + 1
64 pdepth = curdepth + 1
@@ -68,13 +72,14 b' def _genrevancestors(repo, revs, followf'
68 if pctx.rev() != node.nullrev:
72 if pctx.rev() != node.nullrev:
69 heapq.heappush(pendingheap, (-pctx.rev(), pdepth))
73 heapq.heappush(pendingheap, (-pctx.rev(), pdepth))
70
74
71 def revancestors(repo, revs, followfirst, stopdepth=None):
75 def revancestors(repo, revs, followfirst, startdepth=None, stopdepth=None):
72 """Like revlog.ancestors(), but supports additional options, includes
76 """Like revlog.ancestors(), but supports additional options, includes
73 the given revs themselves, and returns a smartset
77 the given revs themselves, and returns a smartset
74
78
75 Scan ends at the stopdepth (exlusive) if specified.
79 Scan ends at the stopdepth (exlusive) if specified. Revisions found
80 earlier than the startdepth are omitted.
76 """
81 """
77 gen = _genrevancestors(repo, revs, followfirst, stopdepth)
82 gen = _genrevancestors(repo, revs, followfirst, startdepth, stopdepth)
78 return generatorset(gen, iterasc=False)
83 return generatorset(gen, iterasc=False)
79
84
80 def revdescendants(repo, revs, followfirst):
85 def revdescendants(repo, revs, followfirst):
@@ -238,11 +238,12 b' def ancestor(repo, subset, x):'
238 return baseset([anc.rev()])
238 return baseset([anc.rev()])
239 return baseset()
239 return baseset()
240
240
241 def _ancestors(repo, subset, x, followfirst=False, stopdepth=None):
241 def _ancestors(repo, subset, x, followfirst=False, startdepth=None,
242 stopdepth=None):
242 heads = getset(repo, fullreposet(repo), x)
243 heads = getset(repo, fullreposet(repo), x)
243 if not heads:
244 if not heads:
244 return baseset()
245 return baseset()
245 s = dagop.revancestors(repo, heads, followfirst, stopdepth)
246 s = dagop.revancestors(repo, heads, followfirst, startdepth, stopdepth)
246 return subset & s
247 return subset & s
247
248
248 @predicate('ancestors(set[, depth])', safe=True)
249 @predicate('ancestors(set[, depth])', safe=True)
@@ -253,18 +254,26 b' def ancestors(repo, subset, x):'
253 If depth is specified, the result only includes changesets up to
254 If depth is specified, the result only includes changesets up to
254 the specified generation.
255 the specified generation.
255 """
256 """
256 args = getargsdict(x, 'ancestors', 'set depth')
257 # startdepth is for internal use only until we can decide the UI
258 args = getargsdict(x, 'ancestors', 'set depth startdepth')
257 if 'set' not in args:
259 if 'set' not in args:
258 # i18n: "ancestors" is a keyword
260 # i18n: "ancestors" is a keyword
259 raise error.ParseError(_('ancestors takes at least 1 argument'))
261 raise error.ParseError(_('ancestors takes at least 1 argument'))
260 stopdepth = None
262 startdepth = stopdepth = None
263 if 'startdepth' in args:
264 n = getinteger(args['startdepth'],
265 "ancestors expects an integer startdepth")
266 if n < 0:
267 raise error.ParseError("negative startdepth")
268 startdepth = n
261 if 'depth' in args:
269 if 'depth' in args:
262 # i18n: "ancestors" is a keyword
270 # i18n: "ancestors" is a keyword
263 n = getinteger(args['depth'], _("ancestors expects an integer depth"))
271 n = getinteger(args['depth'], _("ancestors expects an integer depth"))
264 if n < 0:
272 if n < 0:
265 raise error.ParseError(_("negative depth"))
273 raise error.ParseError(_("negative depth"))
266 stopdepth = n + 1
274 stopdepth = n + 1
267 return _ancestors(repo, subset, args['set'], stopdepth=stopdepth)
275 return _ancestors(repo, subset, args['set'],
276 startdepth=startdepth, stopdepth=stopdepth)
268
277
269 @predicate('_firstancestors', safe=True)
278 @predicate('_firstancestors', safe=True)
270 def _firstancestors(repo, subset, x):
279 def _firstancestors(repo, subset, x):
@@ -903,6 +903,29 b' test ancestors with depth limit'
903 6
903 6
904 5
904 5
905
905
906 (walk 2nd and 3rd ancestors)
907
908 $ log 'reverse(ancestors(7, depth=3, startdepth=2))'
909 5
910 4
911 3
912 2
913
914 (interleaved: '4' would be missing if higher-depth ancestors weren't scanned)
915
916 $ log 'reverse(ancestors(7+8, depth=2, startdepth=2))'
917 5
918 4
919 2
920
921 (note that 'ancestors(x, depth=y, startdepth=z)' does not identical to
922 'ancestors(x, depth=y) - ancestors(x, depth=z-1)' because a node may have
923 multiple depths)
924
925 $ log 'reverse(ancestors(7+8, depth=2) - ancestors(7+8, depth=1))'
926 5
927 2
928
906 test bad arguments passed to ancestors()
929 test bad arguments passed to ancestors()
907
930
908 $ log 'ancestors(., depth=-1)'
931 $ log 'ancestors(., depth=-1)'
General Comments 0
You need to be logged in to leave comments. Login now