comparison mercurial/revlogutils/rewrite.py @ 47821: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 c02ce6def30c
children 2174f54aab18 531d26b1390a
comparison
equal deleted inserted replaced
47820:436932c2cfaa 47821:c30ca163b45e
27 ENTRY_PARENT_1, 27 ENTRY_PARENT_1,
28 ENTRY_PARENT_2, 28 ENTRY_PARENT_2,
29 ENTRY_SIDEDATA_COMPRESSED_LENGTH, 29 ENTRY_SIDEDATA_COMPRESSED_LENGTH,
30 ENTRY_SIDEDATA_COMPRESSION_MODE, 30 ENTRY_SIDEDATA_COMPRESSION_MODE,
31 ENTRY_SIDEDATA_OFFSET, 31 ENTRY_SIDEDATA_OFFSET,
32 REVIDX_ISCENSORED,
32 REVLOGV0, 33 REVLOGV0,
33 REVLOGV1, 34 REVLOGV1,
34 ) 35 )
35 from ..i18n import _ 36 from ..i18n import _
36 37
37 from .. import ( 38 from .. import (
38 error, 39 error,
40 mdiff,
39 pycompat, 41 pycompat,
40 revlogutils, 42 revlogutils,
41 util, 43 util,
42 ) 44 )
43 from ..utils import ( 45 from ..utils import (
717 continue 719 continue
718 if not dry_run: 720 if not dry_run:
719 _reorder_filelog_parents(repo, fl, sorted(to_fix)) 721 _reorder_filelog_parents(repo, fl, sorted(to_fix))
720 722
721 723
724 def filter_delta_issue6528(revlog, deltas_iter):
725 """filter incomind deltas to repaire issue 6528 on the fly"""
726 metadata_cache = {}
727
728 deltacomputer = deltas.deltacomputer(revlog)
729
730 for rev, d in enumerate(deltas_iter, len(revlog)):
731 (
732 node,
733 p1_node,
734 p2_node,
735 linknode,
736 deltabase,
737 delta,
738 flags,
739 sidedata,
740 ) = d
741
742 if not revlog.index.has_node(deltabase):
743 raise error.LookupError(
744 deltabase, revlog.radix, _(b'unknown parent')
745 )
746 base_rev = revlog.rev(deltabase)
747 if not revlog.index.has_node(p1_node):
748 raise error.LookupError(p1_node, revlog.radix, _(b'unknown parent'))
749 p1_rev = revlog.rev(p1_node)
750 if not revlog.index.has_node(p2_node):
751 raise error.LookupError(p2_node, revlog.radix, _(b'unknown parent'))
752 p2_rev = revlog.rev(p2_node)
753
754 is_censored = lambda: bool(flags & REVIDX_ISCENSORED)
755 delta_base = lambda: revlog.rev(delta_base)
756 delta_base = lambda: base_rev
757 parent_revs = lambda: (p1_rev, p2_rev)
758
759 def full_text():
760 # note: being able to reuse the full text computation in the
761 # underlying addrevision would be useful however this is a bit too
762 # intrusive the for the "quick" issue6528 we are writing before the
763 # 5.8 release
764 textlen = mdiff.patchedsize(revlog.size(base_rev), delta)
765
766 revinfo = revlogutils.revisioninfo(
767 node,
768 p1_node,
769 p2_node,
770 [None],
771 textlen,
772 (base_rev, delta),
773 flags,
774 )
775 # cached by the global "writing" context
776 assert revlog._writinghandles is not None
777 if revlog._inline:
778 fh = revlog._writinghandles[0]
779 else:
780 fh = revlog._writinghandles[1]
781 return deltacomputer.buildtext(revinfo, fh)
782
783 is_affected = _is_revision_affected_fast_inner(
784 is_censored,
785 delta_base,
786 lambda: delta,
787 full_text,
788 parent_revs,
789 rev,
790 metadata_cache,
791 )
792 if is_affected:
793 d = (
794 node,
795 p2_node,
796 p1_node,
797 linknode,
798 deltabase,
799 delta,
800 flags,
801 sidedata,
802 )
803 yield d
804
805
722 def repair_issue6528( 806 def repair_issue6528(
723 ui, repo, dry_run=False, to_report=None, from_report=None, paranoid=False 807 ui, repo, dry_run=False, to_report=None, from_report=None, paranoid=False
724 ): 808 ):
725 from .. import store # avoid cycle 809 from .. import store # avoid cycle
726 810