diff mercurial/copies.py @ 34295:fc3b8483c6cb

copytrace: use the full copytracing method if only drafts are involved This patch adds the functionality to use the full copytracing even if `experimental.copytrace = heuristics` in cases when drafts are involved. This is also a part of copytrace extension in fbext. This also adds tests which are also taken from fbext. .. feature:: The `heuristics` option for `experimental.copytrace` performs full copytracing if both source and destination branches contains non-public changsets only. Differential Revision: https://phab.mercurial-scm.org/D625
author Pulkit Goyal <7895pulkit@gmail.com>
date Sun, 03 Sep 2017 20:06:45 +0530
parents 036d47d7cf39
children 1826d695ad58
line wrap: on
line diff
--- a/mercurial/copies.py	Fri Sep 15 10:43:22 2017 -0700
+++ b/mercurial/copies.py	Sun Sep 03 20:06:45 2017 +0530
@@ -15,6 +15,7 @@
     match as matchmod,
     node,
     pathutil,
+    phases,
     scmutil,
     util,
 )
@@ -367,10 +368,27 @@
     if copytracing == 'off':
         return {}, {}, {}, {}, {}
     elif copytracing == 'heuristics':
+        # Do full copytracing if only drafts are involved as that will be fast
+        # enough and will also cover the copies which can be missed by
+        # heuristics
+        if _isfullcopytraceable(c1, base):
+            return _fullcopytracing(repo, c1, c2, base)
         return _heuristicscopytracing(repo, c1, c2, base)
     else:
         return _fullcopytracing(repo, c1, c2, base)
 
+def _isfullcopytraceable(c1, base):
+    """ Checks that if base, source and destination are all draft branches, if
+    yes let's use the full copytrace algorithm for increased capabilities since
+    it will be fast enough.
+    """
+
+    nonpublicphases = set([phases.draft, phases.secret])
+
+    if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases):
+        return True
+    return False
+
 def _fullcopytracing(repo, c1, c2, base):
     """ The full copytracing algorithm which finds all the new files that were
     added from merge base up to the top commit and for each file it checks if