# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 1504386241 -19800 # Node ID b4b196092cc3121491e7c27f1cc500bd6f179033 # Parent 26531db4647a295dd54e97c0e606f6a5624042ec 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 diff -r 26531db4647a -r b4b196092cc3 mercurial/copies.py --- 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 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 diff -r 26531db4647a -r b4b196092cc3 tests/test-copy-move-merge.t --- 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