Patchwork [2,of,8] dagop: copy basefilectx.ancestors() to free function

login
register
mail settings
Submitter Yuya Nishihara
Date Dec. 6, 2017, 3:05 p.m.
Message ID <fe473251da338771d6fa.1512572746@mimosa>
Download mbox | patch
Permalink /patch/25971/
State Accepted
Headers show

Comments

Yuya Nishihara - Dec. 6, 2017, 3:05 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1474532213 -32400
#      Thu Sep 22 17:16:53 2016 +0900
# Node ID fe473251da338771d6fa4d0cbbf1e3d3f5843d0e
# Parent  1bccb52bee2a1c8fee2d208f28c25a9e063aaf61
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.

Patch

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: