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(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.
@@ -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):