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 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/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')