# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 1507582503 -19800 # Node ID f05a6e015eccd165098be407a5f0ea61aa83bb09 # Parent 78d9a7b7cdb62227e852bc29a1687aca0a85de9c copies: add a config to limit the number of candidates to check in heuristics The heuristics algorithm find possible candidates for move/copy and then check whether they are actually a copy or move. In some cases, there can be lot of candidates possible which can actually slow down the algorithm. This patch introduces a config option `experimental.copytrace.movecandidateslimit` using which one can limit the candidates to check. The limit defaults to 100. Thanks to Yuya for suggesting to skip copytracing for that file with a warning. Differential Revision: https://phab.mercurial-scm.org/D987 diff -r 78d9a7b7cdb6 -r f05a6e015ecc mercurial/configitems.py --- a/mercurial/configitems.py Tue Oct 17 10:31:44 2017 -0700 +++ b/mercurial/configitems.py Tue Oct 10 02:25:03 2017 +0530 @@ -330,6 +330,9 @@ coreconfigitem('experimental', 'copytrace', default='on', ) +coreconfigitem('experimental', 'copytrace.movecandidateslimit', + default=100, +) coreconfigitem('experimental', 'copytrace.sourcecommitlimit', default=100, ) diff -r 78d9a7b7cdb6 -r f05a6e015ecc mercurial/copies.py --- a/mercurial/copies.py Tue Oct 17 10:31:44 2017 -0700 +++ b/mercurial/copies.py Tue Oct 10 02:25:03 2017 +0530 @@ -11,6 +11,8 @@ import heapq import os +from .i18n import _ + from . import ( match as matchmod, node, @@ -644,6 +646,11 @@ [experimental] copytrace = heuristics + + In some cases the copy/move candidates found by heuristics can be very large + in number and that will make the algorithm slow. The number of possible + candidates to check can be limited by using the config + `experimental.copytrace.movecandidateslimit` which defaults to 100. """ if c1.rev() is None: @@ -704,6 +711,17 @@ # f is guaranteed to be present in c2, that's why # c2.filectx(f) won't fail f2 = c2.filectx(f) + # we can have a lot of candidates which can slow down the heuristics + # config value to limit the number of candidates moves to check + maxcandidates = repo.ui.configint('experimental', + 'copytrace.movecandidateslimit') + + if len(movecandidates) > maxcandidates: + repo.ui.status(_("skipping copytracing for '%s', more " + "candidates than the limit: %d\n") + % (f, len(movecandidates))) + continue + for candidate in movecandidates: f1 = c1.filectx(candidate) if _related(f1, f2, anc.rev()): diff -r 78d9a7b7cdb6 -r f05a6e015ecc tests/test-copytrace-heuristics.t --- a/tests/test-copytrace-heuristics.t Tue Oct 17 10:31:44 2017 -0700 +++ b/tests/test-copytrace-heuristics.t Tue Oct 10 02:25:03 2017 +0530 @@ -201,6 +201,65 @@ $ cd .. $ rm -rf repo +Test the copytrace.movecandidateslimit with many move candidates +---------------------------------------------------------------- + + $ hg init repo + $ initclient repo + $ cd repo + $ echo a > a + $ hg add a + $ hg ci -m initial + $ hg mv a foo + $ echo a > b + $ echo a > c + $ echo a > d + $ echo a > e + $ echo a > f + $ echo a > g + $ hg add b + $ hg add c + $ hg add d + $ hg add e + $ hg add f + $ hg add g + $ hg ci -m 'mv a foo, add many files' + $ hg up -q ".^" + $ echo b > a + $ hg ci -m 'mod a' + created new head + + $ hg log -G -T 'changeset: {node}\n desc: {desc}\n' + @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e + | desc: mod a + | o changeset: 8329d5c6bf479ec5ca59b9864f3f45d07213f5a4 + |/ desc: mv a foo, add many files + o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 + desc: initial + +With small limit + + $ hg rebase -s 2 -d 1 --config experimental.copytrace.movecandidateslimit=0 + rebasing 2:ef716627c70b "mod a" (tip) + skipping copytracing for 'a', more candidates than the limit: 7 + other [source] changed a which local [dest] deleted + use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u + unresolved conflicts (see hg resolve, then hg rebase --continue) + [1] + + $ hg rebase --abort + rebase aborted + +With default limit which is 100 + + $ hg rebase -s 2 -d 1 + rebasing 2:ef716627c70b "mod a" (tip) + merging foo and a to foo + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg (glob) + + $ cd .. + $ rm -rf repo + Move file in one branch and delete it in another -----------------------------------------------