diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -176,6 +176,9 @@ coreconfigitem('experimental', 'copytrace', default='on', ) +coreconfigitem('experimental', 'copytrace.sourcecommitlimit', + default=100 +) coreconfigitem('experimental', 'crecordtest', default=None, ) diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -371,13 +371,13 @@ # 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): + if _isfullcopytraceable(repo.ui, 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): +def _isfullcopytraceable(ui, 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. @@ -386,7 +386,10 @@ nonpublicphases = set([phases.draft, phases.secret]) if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases): - return True + sourcecommitlimit = ui.configint('experimental', + 'copytrace.sourcecommitlimit') + commits = len(repo.revs('%d::%d', base.rev(), c1.rev())) + return commits < sourcecommitlimit return False def _fullcopytracing(repo, c1, c2, base):