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
--- 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