changeset 34078:b4b196092cc3

copytrace: move the default copytracing algorithm in a new function We are going to introduce a new fast heuristic based copytracing algorithm, so lets make mergecopies the function which decides which algorithm to go with and then calls the related function. While I was here, I add a line in test-copy-move-merge.t saying its a test related to the full copytracing algorithm. Differential Revision: https://phab.mercurial-scm.org/D622
author Pulkit Goyal <7895pulkit@gmail.com>
date Sun, 03 Sep 2017 02:34:01 +0530
parents 26531db4647a
children 1104718fb090
files mercurial/copies.py tests/test-copy-move-merge.t
diffstat 2 files changed, 23 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/copies.py	Sun Sep 03 01:52:19 2017 +0530
+++ b/mercurial/copies.py	Sun Sep 03 02:34:01 2017 +0530
@@ -306,9 +306,13 @@
 
 def mergecopies(repo, c1, c2, base):
     """
-    The basic algorithm for copytracing. Copytracing is used in commands like
-    rebase, merge, unshelve, etc to merge files that were moved/ copied in one
-    merge parent and modified in another. For example:
+    The function calling different copytracing algorithms on the basis of config
+    which find moves and copies between context c1 and c2 that are relevant for
+    merging. 'base' will be used as the merge base.
+
+    Copytracing is used in commands like rebase, merge, unshelve, etc to merge
+    files that were moved/ copied in one merge parent and modified in another.
+    For example:
 
     o          ---> 4 another commit
     |
@@ -324,13 +328,6 @@
 
     ```other changed <file> which local deleted```
 
-    If copytrace is enabled, this function finds all the new files that were
-    added from merge base up to the top commit (here 4), and for each file it
-    checks if this file was copied from another file (a.txt in the above case).
-
-    Find moves and copies between context c1 and c2 that are relevant
-    for merging. 'base' will be used as the merge base.
-
     Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
     "dirmove".
 
@@ -360,12 +357,24 @@
     if c2.node() is None and c1.node() == repo.dirstate.p1():
         return repo.dirstate.copies(), {}, {}, {}, {}
 
+    copytracing = repo.ui.config('experimental', 'copytrace')
+
     # Copy trace disabling is explicitly below the node == p1 logic above
     # because the logic above is required for a simple copy to be kept across a
     # rebase.
-    if repo.ui.config('experimental', 'copytrace') == 'off':
+    if copytracing == 'off':
         return {}, {}, {}, {}, {}
+    else:
+        return _fullcopytracing(repo, c1, c2, base)
 
+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
+    this file was copied from another file.
+
+    This is pretty slow when a lot of changesets are involved but will track all
+    the copies.
+    """
     # In certain scenarios (e.g. graft, update or rebase), base can be
     # overridden We still need to know a real common ancestor in this case We
     # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
--- a/tests/test-copy-move-merge.t	Sun Sep 03 01:52:19 2017 +0530
+++ b/tests/test-copy-move-merge.t	Sun Sep 03 02:34:01 2017 +0530
@@ -1,3 +1,6 @@
+Test for the full copytracing algorithm
+=======================================
+
   $ hg init t
   $ cd t