diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -376,13 +376,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(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. @@ -391,7 +391,14 @@ nonpublicphases = set([phases.draft, phases.secret]) if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases): - return True + ctx = c1 + commits = 0 + sourcecommitlimit = ui.configint('experimental', + 'copytrace.sourcecommitlimit', 100) + while ctx != base and commits != sourcecommitlimit: + ctx = ctx.p1() + commits += 1 + return commits < sourcecommitlimit return False def _fullcopytracing(repo, c1, c2, base):