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: