D7076: copies: compute the exact set of revision to walk

marmoute (Pierre-Yves David) phabricator at mercurial-scm.org
Wed Oct 16 19:12:46 EDT 2019


marmoute updated this revision to Diff 17279.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7076?vs=17278&id=17279

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7076/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7076

AFFECTED FILES
  mercurial/copies.py

CHANGE DETAILS

diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -8,7 +8,6 @@
 from __future__ import absolute_import
 
 import collections
-import heapq
 import os
 
 from .i18n import _
@@ -229,6 +228,8 @@
 
     cl = repo.changelog
     missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
+    mrset = set(missingrevs)
+    roots = set()
     for r in missingrevs:
         for p in cl.parentrevs(r):
             if p == node.nullrev:
@@ -237,17 +238,23 @@
                 children[p] = [r]
             else:
                 children[p].append(r)
+            if p not in mrset:
+                roots.add(p)
+    if not roots:
+        # no common revision to track copies from
+        return {}
+    min_root = min(roots)
 
-    roots = set(children) - set(missingrevs)
-    work = list(roots)
+    from_head = set(cl.reachableroots(min_root, [b.rev()], list(roots), includepath=True))
+
+    iterrevs = set(from_head)
+    iterrevs &= mrset
+    iterrevs.update(roots)
+    iterrevs.remove(b.rev())
     all_copies = {r: {} for r in roots}
-    heapq.heapify(work)
     alwaysmatch = match.always()
-    while work:
-        r = heapq.heappop(work)
+    for r in sorted(iterrevs):
         copies = all_copies.pop(r)
-        if r == b.rev():
-            return copies
         for i, c in enumerate(children[r]):
             p1, p2, p1copies, p2copies, removed = revinfo(c)
             if r == p1:
@@ -273,7 +280,6 @@
                     del newcopies[f]
             othercopies = all_copies.get(c)
             if othercopies is None:
-                heapq.heappush(work, c)
                 all_copies[c] = newcopies
             else:
                 # we are the second parent to work on c, we need to merge our
@@ -293,7 +299,7 @@
                 else:
                     newcopies.update(othercopies)
                     all_copies[c] = newcopies
-    assert False
+    return all_copies[b.rev()]
 
 
 def _forwardcopies(a, b, base=None, match=None):



To: marmoute, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list