diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1892,6 +1892,11 @@ default=True, alias=[(b'format', b'aggressivemergedeltas')], ) +coreconfigitem( + b'storage', + b'revlog.issue6528.fix-incoming', + default=True, +) # experimental as long as rust is experimental (or a C version is implemented) coreconfigitem( b'storage', diff --git a/mercurial/filelog.py b/mercurial/filelog.py --- a/mercurial/filelog.py +++ b/mercurial/filelog.py @@ -38,6 +38,8 @@ # Used by LFS. self._revlog.filename = path self.nullid = self._revlog.nullid + opts = opener.options + self._fix_issue6528 = opts.get(b'issue6528.fix-incoming', True) def __len__(self): return len(self._revlog) @@ -160,7 +162,8 @@ with self._revlog._writing(transaction): - deltas = rewrite.filter_delta_issue6528(self._revlog, deltas) + if self._fix_issue6528: + deltas = rewrite.filter_delta_issue6528(self._revlog, deltas) return self._revlog.addgroup( deltas, diff --git a/mercurial/helptext/config.txt b/mercurial/helptext/config.txt --- a/mercurial/helptext/config.txt +++ b/mercurial/helptext/config.txt @@ -2043,6 +2043,21 @@ Control the strategy Mercurial uses internally to store history. Options in this category impact performance and repository size. +``revlog.issue6528.fix-incoming`` + Version 5.8 of Mercurial had a bug leading to altering the parent of file + revision with copy information (or any other metadata) on exchange. This + leads to the copy metadata to be overlooked by various internal logic. The + issue was fixed in Mercurial 5.8.1. + (See https://bz.mercurial-scm.org/show_bug.cgi?id=6528 for details) + + As a result Mercurial is now checking and fixing incoming file revisions to + make sure there parents are in the right order. This behavior can be + disabled by setting this option to `no`. This apply to revisions added + through push, pull, clone and unbundle. + + To fix affected revisions that already exist within the repository, one can + use :hg:`debug-repair-issue-6528`. + ``revlog.optimize-delta-parent-choice`` When storing a merge revision, both parents will be equally considered as a possible delta base. This results in better delta selection and improved diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1043,6 +1043,9 @@ ) options[b'deltabothparents'] = deltabothparents + issue6528 = ui.configbool(b'storage', b'revlog.issue6528.fix-incoming') + options[b'issue6528.fix-incoming'] = issue6528 + lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta') lazydeltabase = False if lazydelta: diff --git a/tests/test-issue6528.t b/tests/test-issue6528.t --- a/tests/test-issue6528.t +++ b/tests/test-issue6528.t @@ -524,3 +524,104 @@ no affected revisions were found $ cd .. + +A config option can disable the fixing of the bad bundle on the fly +------------------------------------------------------------------- + + + +from a v1 bundle +~~~~~~~~~~~~~~~~ + + $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v1 + bzip2-v1 + + $ hg init unbundle-v1-no-fix + $ cd unbundle-v1-no-fix + + $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v1 --config storage.revlog.issue6528.fix-incoming=no + adding changesets + adding manifests + adding file changes + added 8 changesets with 12 changes to 4 files + new changesets f5a5a568022f:3beabb508514 (8 drafts) + (run 'hg update' to get a working copy) + +Check that revision were not fixed on the fly + + $ hg debugrevlogindex b.txt + rev linkrev nodeid p1 p2 + 0 2 05b806ebe5ea 000000000000 000000000000 + 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 + 2 6 216a5fe8b8ed 000000000000 000000000000 + 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 + + $ hg debugrevlogindex D.txt + rev linkrev nodeid p1 p2 + 0 6 2a8d3833f2fb 000000000000 000000000000 + 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 + +That we do see the symptoms of the bug + + $ hg up -- -1 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg status + M D.txt (?) + M b.txt (?) + +And that the repair command find issue to fix. + + $ hg debug-repair-issue6528 --dry-run + found affected revision 1 for filelog 'data/D.txt.i' + found affected revision 1 for filelog 'data/b.txt.i' + found affected revision 3 for filelog 'data/b.txt.i' + + $ cd .. + +from a v2 bundle +~~~~~~~~~~~~~~~~ + + $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v2 + bzip2-v2 + + $ hg init unbundle-v2-no-fix + $ cd unbundle-v2-no-fix + + $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v2 --config storage.revlog.issue6528.fix-incoming=no + adding changesets + adding manifests + adding file changes + added 8 changesets with 12 changes to 4 files + new changesets f5a5a568022f:3beabb508514 (8 drafts) + (run 'hg update' to get a working copy) + +Check that revision were not fixed on the fly + + $ hg debugrevlogindex b.txt + rev linkrev nodeid p1 p2 + 0 2 05b806ebe5ea 000000000000 000000000000 + 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 + 2 6 216a5fe8b8ed 000000000000 000000000000 + 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 + + $ hg debugrevlogindex D.txt + rev linkrev nodeid p1 p2 + 0 6 2a8d3833f2fb 000000000000 000000000000 + 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 + +That we do see the symptoms of the bug + + $ hg up -- -1 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg status + M D.txt (?) + M b.txt (?) + +And that the repair command find issue to fix. + + $ hg debug-repair-issue6528 --dry-run + found affected revision 1 for filelog 'data/D.txt.i' + found affected revision 1 for filelog 'data/b.txt.i' + found affected revision 3 for filelog 'data/b.txt.i' + + $ cd ..