# HG changeset patch # User Yuya Nishihara # Date 2016-09-22 08:16:53 # Node ID 0d27685b4a2fd443d9235b9854e1beffa78e9209 # Parent 2af38229f147f14b6dc518d90d3286076fa3137a dagop: copy basefilectx.ancestors() to free function The primary goal of this series is to make follow() support multiple start revisions. dagop.filectxancestors() will be extended to take multiple filectxs. basefilectx.ancestors() is not forwarded to this function because doing that would resurrect the performance issue fixed by 24b57c3899f8. diff --git a/mercurial/dagop.py b/mercurial/dagop.py --- a/mercurial/dagop.py +++ b/mercurial/dagop.py @@ -75,6 +75,23 @@ def _walkrevtree(pfunc, revs, startdepth if prev != node.nullrev: heapq.heappush(pendingheap, (heapsign * prev, pdepth)) +def filectxancestors(fctx, followfirst=False): + """Like filectx.ancestors()""" + visit = {} + c = fctx + if followfirst: + cut = 1 + else: + cut = None + + while True: + for parent in c.parents()[:cut]: + visit[(parent.linkrev(), parent.filenode())] = parent + if not visit: + break + c = visit.pop(max(visit)) + yield c + def _genrevancestors(repo, revs, followfirst, startdepth, stopdepth, cutfunc): if followfirst: cut = 1 diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -930,7 +930,8 @@ def _follow(repo, subset, x, name, follo s = set() for fname in files: fctx = c[fname] - s = s.union(set(c.rev() for c in fctx.ancestors(followfirst))) + a = dagop.filectxancestors(fctx, followfirst) + s = s.union(set(c.rev() for c in a)) # include the revision responsible for the most recent version s.add(fctx.introrev()) else: