copies: improve logic of deciding copytracing on based of config options
authorPulkit Goyal <pulkit@yandex-team.ru>
Wed, 29 Aug 2018 18:52:09 +0300
changeset 39366 a41497b5117c
parent 39365 659e2bbd0c20
child 39367 83f8f7b9fa60
copies: improve logic of deciding copytracing on based of config options Few months ago or maybe a year ago, I imported Fb's heuristics based copytracing algorithms. While importing that, I renamed `experimental.disablecopytrace` with `experimental.copytrace` and the behavior of the new config option was like this: * "heuristics" : Fb's heuristic copytracing algorithm * "off" : copytracing is turned off * something else: copytracing is on This is the behavior right now also and this is bad because it hardcodes the string 'off' to turn off the copytracing. On big repositories, copytracing is very slow and people wants to turn copytracing off. However if the user sets it to 'False', 'Off', '0', none of them is going to disbale copytracing while they should. I lacked the understanding of why this can be bad when I coded it. After this patch, the new behavior of the config option will be: * "heuristics": Fb's heuristic copytracing algorithm * '0', 'false', 'off', 'never', 'no', 'NO', all the values which repo.ui.configbool() evaluates to False: copytracing in turned off * something else: copytracing is on Since 'off' still evaluates to copytracing being turned off, this is not BC. Also the config option is experimental. Differential Revision: https://phab.mercurial-scm.org/D4416
mercurial/copies.py
--- a/mercurial/copies.py	Thu Aug 30 13:29:03 2018 +0300
+++ b/mercurial/copies.py	Wed Aug 29 18:52:09 2018 +0300
@@ -20,6 +20,9 @@
     scmutil,
     util,
 )
+from .utils import (
+    stringutil,
+)
 
 def _findlimit(repo, a, b):
     """
@@ -366,19 +369,22 @@
         return repo.dirstate.copies(), {}, {}, {}, {}
 
     copytracing = repo.ui.config('experimental', 'copytrace')
+    boolctrace = stringutil.parsebool(copytracing)
 
     # Copy trace disabling is explicitly below the node == p1 logic above
     # because the logic above is required for a simple copy to be kept across a
     # rebase.
-    if copytracing == 'off':
-        return {}, {}, {}, {}, {}
-    elif copytracing == 'heuristics':
+    if copytracing == 'heuristics':
         # Do full copytracing if only non-public revisions are involved as
         # that will be fast enough and will also cover the copies which could
         # be missed by heuristics
         if _isfullcopytraceable(repo, c1, base):
             return _fullcopytracing(repo, c1, c2, base)
         return _heuristicscopytracing(repo, c1, c2, base)
+    elif boolctrace is False:
+        # stringutil.parsebool() returns None when it is unable to parse the
+        # value, so we should rely on making sure copytracing is on such cases
+        return {}, {}, {}, {}, {}
     else:
         return _fullcopytracing(repo, c1, c2, base)
 
@@ -870,8 +876,10 @@
     copies between fromrev and rev.
     """
     exclude = {}
+    ctraceconfig = repo.ui.config('experimental', 'copytrace')
+    bctrace = stringutil.parsebool(ctraceconfig)
     if (skiprev is not None and
-        repo.ui.config('experimental', 'copytrace') != 'off'):
+        (ctraceconfig == 'heuristics' or bctrace or bctrace is None)):
         # copytrace='off' skips this line, but not the entire function because
         # the line below is O(size of the repo) during a rebase, while the rest
         # of the function is much faster (and is required for carrying copy