copies: add an devel option to trace all files
authorPierre-Yves David <pierre-yves.david@octobus.net>
Sat, 16 Jan 2021 00:03:18 +0100
changeset 46480 e948ad0dcbe2
parent 46479 095fa99ae5f5
child 46481 29e3e46b0a22
copies: add an devel option to trace all files Filelog based copy tracing only trace copy for file that have been added. This is a trade off between skipping some rare copy case in exchange for avoiding atrocious-to-the-point-of-unusable performance. The changeset centric copy tracing does not need this trade off and naturally trace all copy, include the one involving non-new files. In order to ease the comparison from both algorithm, we add a small devel option to trace copy for all files in the target revisions. Differential Revision: https://phab.mercurial-scm.org/D9796
mercurial/configitems.py
mercurial/copies.py
tests/test-copies.t
tests/test-copy.t
--- a/mercurial/configitems.py	Thu Jan 28 15:26:33 2021 +0100
+++ b/mercurial/configitems.py	Sat Jan 16 00:03:18 2021 +0100
@@ -615,6 +615,12 @@
     b'check-relroot',
     default=False,
 )
+# Track copy information for all file, not just "added" one (very slow)
+coreconfigitem(
+    b'devel',
+    b'copy-tracing.trace-all-files',
+    default=False,
+)
 coreconfigitem(
     b'devel',
     b'default-date',
--- a/mercurial/copies.py	Thu Jan 28 15:26:33 2021 +0100
+++ b/mercurial/copies.py	Sat Jan 16 00:03:18 2021 +0100
@@ -152,13 +152,21 @@
     if b.p1() == a and b.p2().node() == nullid:
         filesmatcher = matchmod.exact(b.files())
         forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
-    missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
+    if repo.ui.configbool(b'devel', b'copy-tracing.trace-all-files'):
+        missing = list(b.walk(match))
+        # _computeforwardmissing(a, b, match=forwardmissingmatch)
+        if debug:
+            dbg(b'debug.copies:      searching all files: %d\n' % len(missing))
+    else:
+        missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
+        if debug:
+            dbg(
+                b'debug.copies:      missing files to search: %d\n'
+                % len(missing)
+            )
 
     ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
 
-    if debug:
-        dbg(b'debug.copies:      missing files to search: %d\n' % len(missing))
-
     for f in sorted(missing):
         if debug:
             dbg(b'debug.copies:        tracing file: %s\n' % f)
--- a/tests/test-copies.t	Thu Jan 28 15:26:33 2021 +0100
+++ b/tests/test-copies.t	Sat Jan 16 00:03:18 2021 +0100
@@ -95,6 +95,8 @@
   x -> y
   $ hg debugpathcopies 0 1
   x -> y (no-filelog !)
+  $ hg debugpathcopies 0 1  --config devel.copy-tracing.trace-all-files=yes
+  x -> y
 
 Copy a file onto another file with same content. If metadata is stored in changeset, this does not
 produce a new filelog entry. The changeset's "files" entry should still list the file.
@@ -113,6 +115,8 @@
   x -> x2
   $ hg debugpathcopies 0 1
   x -> x2 (no-filelog !)
+  $ hg debugpathcopies 0 1  --config devel.copy-tracing.trace-all-files=yes
+  x -> x2
 
 Rename file in a loop: x->y->z->x
   $ newrepo
--- a/tests/test-copy.t	Thu Jan 28 15:26:33 2021 +0100
+++ b/tests/test-copy.t	Sat Jan 16 00:03:18 2021 +0100
@@ -228,6 +228,17 @@
 should show no copies
   $ hg st -C
 
+note: since filelog based copy tracing only trace copy for new file, the copy information here is not displayed.
+
+  $ hg status --copies --change .
+  M bar
+
+They are a devel option to walk all file and fine this information anyway.
+
+  $ hg status --copies --change . --config devel.copy-tracing.trace-all-files=yes
+  M bar
+    foo
+
 copy --after on an added file
   $ cp bar baz
   $ hg add baz