Patchwork D11252: debugupgraderepo: add fix-metaencoding-flag pass for issue6528

login
register
mail settings
Submitter phabricator
Date Aug. 4, 2021, 8:42 p.m.
Message ID <differential-rev-PHID-DREV-rxzuojl7qilcknebevwq-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49565/
State New
Headers show

Comments

phabricator - Aug. 4, 2021, 8:42 p.m.
joerg.sonnenberger created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
marmoute added a comment.


  This is similar to D11239 <https://phab.mercurial-scm.org/D11239>, having this done during upgrade too seems useful, but having a simpler/more-focussed command for this seems important (and "on-fly-fix" during exchange too.
  
  Ideally we would take D11239 <https://phab.mercurial-scm.org/D11239> first and reuse its bulding block for that diff afterward.

REPOSITORY
  rHG Mercurial

BRANCH
  stable

REVISION DETAIL
  https://phab.mercurial-scm.org/D11252

AFFECTED FILES
  mercurial/revlog.py
  mercurial/upgrade_utils/actions.py
  mercurial/upgrade_utils/engine.py

CHANGE DETAILS




To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/upgrade_utils/engine.py b/mercurial/upgrade_utils/engine.py
--- a/mercurial/upgrade_utils/engine.py
+++ b/mercurial/upgrade_utils/engine.py
@@ -136,6 +136,10 @@ 
 ):
     """returns the new revlog object created"""
     newrl = None
+    recheckmetaencoding = (
+        upgrade_op.recheckmetaencoding
+        and (rl_type & store.FILEFLAGS_FILELOG) != 0
+    )
     if matchrevlog(upgrade_op.revlogs_to_process, rl_type):
         ui.note(
             _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
@@ -148,6 +152,7 @@ 
             deltareuse=upgrade_op.delta_reuse_mode,
             forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
             sidedatacompanion=sidedatacompanion,
+            recheckmetaencoding=recheckmetaencoding,
         )
     else:
         msg = _(b'blindly copying %s containing %i revisions\n')
diff --git a/mercurial/upgrade_utils/actions.py b/mercurial/upgrade_utils/actions.py
--- a/mercurial/upgrade_utils/actions.py
+++ b/mercurial/upgrade_utils/actions.py
@@ -616,6 +616,22 @@ 
     )
 )
 
+register_optimization(
+    improvement(
+        name=b'fix-metaencoding-flag',
+        type=OPTIMISATION,
+        description=_(
+            b'filelog entries with copy metadata may have been flagged '
+            b'incorrectly in Mercurial 5.8. This option will look for such '
+            b'revisions and fix them.'
+        ),
+        upgrademessage=_(
+            b'revision content will be recomputed; this will likely drastically '
+            b'slow down execution time'
+        ),
+    )
+)
+
 
 def findoptimizations(repo):
     """Determine optimisation that could be used during upgrade"""
@@ -710,6 +726,11 @@ 
         elif b're-delta-fulladd' in self._upgrade_actions_names:
             self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD
 
+        # should this operation search for misordered parents of copy filelog entries
+        self.recheckmetaencoding = (
+            b'fix-metaencoding-flag' in self._upgrade_actions_names
+        )
+
         # should this operation force re-delta of both parents
         self.force_re_delta_both_parents = (
             b're-delta-multibase' in self._upgrade_actions_names
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -2779,6 +2779,7 @@ 
         deltareuse=DELTAREUSESAMEREVS,
         forcedeltabothparents=None,
         sidedatacompanion=None,
+        recheckmetaencoding=False,
     ):
         """Copy this revlog to another, possibly with format changes.
 
@@ -2876,6 +2877,7 @@ 
                 deltareuse,
                 forcedeltabothparents,
                 sidedatacompanion,
+                recheckmetaencoding,
             )
 
         finally:
@@ -2891,10 +2893,18 @@ 
         deltareuse,
         forcedeltabothparents,
         sidedatacompanion,
+        recheckmetaencoding,
     ):
         """perform the core duty of `revlog.clone` after parameter processing"""
+
+        def ismetaencoded(text, flags):
+            return text.startswith(b'\x01\n') and (
+                flags & REVIDX_ISCENSORED == 0
+            )
+
         deltacomputer = deltautil.deltacomputer(destrevlog)
         index = self.index
+
         for rev in self:
             entry = index[rev]
 
@@ -2914,7 +2924,11 @@ 
             # the revlog chunk is a delta.
             cachedelta = None
             rawtext = None
-            if any(sidedataactions) or deltareuse == self.DELTAREUSEFULLADD:
+            if (
+                any(sidedataactions)
+                or deltareuse == self.DELTAREUSEFULLADD
+                or recheckmetaencoding
+            ):
                 dropall = sidedataactions[0]
                 filterout = sidedataactions[1]
                 update = sidedataactions[2]
@@ -2928,6 +2942,13 @@ 
                 sidedata.update(update)
                 if not sidedata:
                     sidedata = None
+                if (
+                    recheckmetaencoding
+                    and ismetaencoded(text, flags)
+                    and p1 != self.nullid
+                    and p2 == self.nullid
+                ):
+                    p1, p2 = p2, p1
 
                 flags |= new_flags
                 flags &= ~dropped_flags