Mercurial > hg-stable
changeset 47816:c30ca163b45e stable
issue6528: also filter delta on the fly when applying a changegroup
This ensure that corrupted clone does not spread corruption to "fixed" version.
This might come at a performance cost, we will had a config option to control
this behavior in the next changesets.
Differential Revision: https://phab.mercurial-scm.org/D11270
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sat, 07 Aug 2021 14:12:28 +0200 |
parents | 436932c2cfaa |
children | 2813d406b036 |
files | mercurial/filelog.py mercurial/revlogutils/rewrite.py tests/bundles/issue6528.hg-v1 tests/bundles/issue6528.hg-v2 tests/test-issue6528.t |
diffstat | 5 files changed, 181 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/filelog.py Sat Aug 07 14:13:53 2021 +0200 +++ b/mercurial/filelog.py Sat Aug 07 14:12:28 2021 +0200 @@ -20,6 +20,7 @@ from .utils import storageutil from .revlogutils import ( constants as revlog_constants, + rewrite, ) @@ -158,6 +159,9 @@ ) with self._revlog._writing(transaction): + + deltas = rewrite.filter_delta_issue6528(self._revlog, deltas) + return self._revlog.addgroup( deltas, linkmapper,
--- a/mercurial/revlogutils/rewrite.py Sat Aug 07 14:13:53 2021 +0200 +++ b/mercurial/revlogutils/rewrite.py Sat Aug 07 14:12:28 2021 +0200 @@ -29,6 +29,7 @@ ENTRY_SIDEDATA_COMPRESSED_LENGTH, ENTRY_SIDEDATA_COMPRESSION_MODE, ENTRY_SIDEDATA_OFFSET, + REVIDX_ISCENSORED, REVLOGV0, REVLOGV1, ) @@ -36,6 +37,7 @@ from .. import ( error, + mdiff, pycompat, revlogutils, util, @@ -719,6 +721,88 @@ _reorder_filelog_parents(repo, fl, sorted(to_fix)) +def filter_delta_issue6528(revlog, deltas_iter): + """filter incomind deltas to repaire issue 6528 on the fly""" + metadata_cache = {} + + deltacomputer = deltas.deltacomputer(revlog) + + for rev, d in enumerate(deltas_iter, len(revlog)): + ( + node, + p1_node, + p2_node, + linknode, + deltabase, + delta, + flags, + sidedata, + ) = d + + if not revlog.index.has_node(deltabase): + raise error.LookupError( + deltabase, revlog.radix, _(b'unknown parent') + ) + base_rev = revlog.rev(deltabase) + if not revlog.index.has_node(p1_node): + raise error.LookupError(p1_node, revlog.radix, _(b'unknown parent')) + p1_rev = revlog.rev(p1_node) + if not revlog.index.has_node(p2_node): + raise error.LookupError(p2_node, revlog.radix, _(b'unknown parent')) + p2_rev = revlog.rev(p2_node) + + is_censored = lambda: bool(flags & REVIDX_ISCENSORED) + delta_base = lambda: revlog.rev(delta_base) + delta_base = lambda: base_rev + parent_revs = lambda: (p1_rev, p2_rev) + + def full_text(): + # note: being able to reuse the full text computation in the + # underlying addrevision would be useful however this is a bit too + # intrusive the for the "quick" issue6528 we are writing before the + # 5.8 release + textlen = mdiff.patchedsize(revlog.size(base_rev), delta) + + revinfo = revlogutils.revisioninfo( + node, + p1_node, + p2_node, + [None], + textlen, + (base_rev, delta), + flags, + ) + # cached by the global "writing" context + assert revlog._writinghandles is not None + if revlog._inline: + fh = revlog._writinghandles[0] + else: + fh = revlog._writinghandles[1] + return deltacomputer.buildtext(revinfo, fh) + + is_affected = _is_revision_affected_fast_inner( + is_censored, + delta_base, + lambda: delta, + full_text, + parent_revs, + rev, + metadata_cache, + ) + if is_affected: + d = ( + node, + p2_node, + p1_node, + linknode, + deltabase, + delta, + flags, + sidedata, + ) + yield d + + def repair_issue6528( ui, repo, dry_run=False, to_report=None, from_report=None, paranoid=False ):
--- a/tests/test-issue6528.t Sat Aug 07 14:13:53 2021 +0200 +++ b/tests/test-issue6528.t Sat Aug 07 14:12:28 2021 +0200 @@ -431,3 +431,96 @@ $ hg debug-repair-issue6528 no affected revisions were found $ hg st + + $ cd .. + +Applying a bad bundle should fix it on the fly +---------------------------------------------- + +from a v1 bundle +~~~~~~~~~~~~~~~~ + + $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v1 + bzip2-v1 + + $ hg init unbundle-v1 + $ cd unbundle-v1 + + $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v1 + 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 fixed on the fly + + $ hg debugrevlogindex b.txt + rev linkrev nodeid p1 p2 + 0 2 05b806ebe5ea 000000000000 000000000000 + 1 3 a58b36ad6b65 000000000000 05b806ebe5ea + 2 6 216a5fe8b8ed 000000000000 000000000000 + 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed + + $ hg debugrevlogindex D.txt + rev linkrev nodeid p1 p2 + 0 6 2a8d3833f2fb 000000000000 000000000000 + 1 7 2a80419dfc31 000000000000 2a8d3833f2fb + +That we don't see the symptoms of the bug + + $ hg up -- -1 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg status + +And that the repair command does not find anything to fix + + $ hg debug-repair-issue6528 + no affected revisions were found + + $ cd .. + +from a v2 bundle +~~~~~~~~~~~~~~~~ + + $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v2 + bzip2-v2 + + $ hg init unbundle-v2 + $ cd unbundle-v2 + + $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v2 + 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 fixed on the fly + + $ hg debugrevlogindex b.txt + rev linkrev nodeid p1 p2 + 0 2 05b806ebe5ea 000000000000 000000000000 + 1 3 a58b36ad6b65 000000000000 05b806ebe5ea + 2 6 216a5fe8b8ed 000000000000 000000000000 + 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed + + $ hg debugrevlogindex D.txt + rev linkrev nodeid p1 p2 + 0 6 2a8d3833f2fb 000000000000 000000000000 + 1 7 2a80419dfc31 000000000000 2a8d3833f2fb + +That we don't see the symptoms of the bug + + $ hg up -- -1 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg status + +And that the repair command does not find anything to fix + + $ hg debug-repair-issue6528 + no affected revisions were found + + $ cd ..