changeset 34311:1826d695ad58

copytrace: add a a new config to limit the number of drafts in heuristics The heuristics options tries to the default full copytracing algorithm if both the source and destination branches contains of non-public changesets only. But this can be slow in cases when we have a lot of drafts. This patch adds a new config option experimental.copytrace.sourcecommitlimit which defaults to 100. This value will be the limit of number of drafts from c1 to base. Incase there are more changesets even though they are draft, the heuristics algorithm will be used. Differential Revision: https://phab.mercurial-scm.org/D763
author Pulkit Goyal <7895pulkit@gmail.com>
date Thu, 21 Sep 2017 15:58:44 +0530
parents 2d0c306a88c2
children d64c2c050b54
files mercurial/configitems.py mercurial/copies.py tests/test-copytrace-heuristics.t
diffstat 3 files changed, 58 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/configitems.py	Tue Sep 26 16:14:57 2017 +0300
+++ b/mercurial/configitems.py	Thu Sep 21 15:58:44 2017 +0530
@@ -176,6 +176,9 @@
 coreconfigitem('experimental', 'copytrace',
     default='on',
 )
+coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
+    default=100,
+)
 coreconfigitem('experimental', 'crecordtest',
     default=None,
 )
--- a/mercurial/copies.py	Tue Sep 26 16:14:57 2017 +0300
+++ b/mercurial/copies.py	Thu Sep 21 15:58:44 2017 +0530
@@ -371,22 +371,27 @@
         # 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, 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(repo, 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.
     """
+    if c1.rev() is None:
+        c1 = c1.p1()
 
     nonpublicphases = set([phases.draft, phases.secret])
 
     if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases):
-        return True
+        sourcecommitlimit = repo.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):
--- a/tests/test-copytrace-heuristics.t	Tue Sep 26 16:14:57 2017 +0300
+++ b/tests/test-copytrace-heuristics.t	Thu Sep 21 15:58:44 2017 +0530
@@ -665,3 +665,50 @@
   dummy
   $ rm -rf server
   $ rm -rf repo
+
+Testing the sourcecommitlimit config
+
+  $ hg init repo
+  $ initclient repo
+  $ cd repo
+  $ echo a > a
+  $ hg ci -Aqm "added a"
+  $ echo "more things" >> a
+  $ hg ci -qm "added more things to a"
+  $ hg up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo b > b
+  $ hg ci -Aqm "added b"
+  $ mkdir foo
+  $ hg mv a foo/bar
+  $ hg ci -m "Moved a to foo/bar"
+  $ hg log -G -T 'changeset {node}\n desc {desc}, phase: {phase}\n'
+  @  changeset b4b0f7880e500b5c364a5f07b4a2b167de7a6fb0
+  |   desc Moved a to foo/bar, phase: draft
+  o  changeset 5f6d8a4bf34ab274ccc9f631c2536964b8a3666d
+  |   desc added b, phase: draft
+  | o  changeset 8b6e13696c38e8445a759516474640c2f8dddef6
+  |/    desc added more things to a, phase: draft
+  o  changeset 9092f1db7931481f93b37d5c9fbcfc341bcd7318
+      desc added a, phase: draft
+
+When the sourcecommitlimit is small and we have more drafts, we use heuristics only
+
+  $ hg rebase -s 8b6e13696 -d . --config experimental.copytrace.sourcecommitlimit=0
+  rebasing 1:8b6e13696c38 "added more things to a"
+  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]
+
+But when we have "sourcecommitlimit > (no. of drafts from base to c1)", we do
+fullcopytracing
+
+  $ hg rebase --abort
+  rebase aborted
+  $ hg rebase -s 8b6e13696 -d .
+  rebasing 1:8b6e13696c38 "added more things to a"
+  merging foo/bar and a to foo/bar
+  saved backup bundle to $TESTTMP/repo/repo/repo/.hg/strip-backup/8b6e13696c38-fc14ac83-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf repo