# HG changeset patch # User Pierre-Yves David # Date 1610751798 -3600 # Node ID e948ad0dcbe2dbea1cd7d2acfdd37348f6f15f60 # Parent 095fa99ae5f5f0c6b30a442b38e5188fd18a8cef 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 diff -r 095fa99ae5f5 -r e948ad0dcbe2 mercurial/configitems.py --- 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', diff -r 095fa99ae5f5 -r e948ad0dcbe2 mercurial/copies.py --- 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) diff -r 095fa99ae5f5 -r e948ad0dcbe2 tests/test-copies.t --- 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 diff -r 095fa99ae5f5 -r e948ad0dcbe2 tests/test-copy.t --- 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