Mercurial > hg
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