diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -2356,7 +2356,8 @@ DELTAREUSEALL = {'always', 'samerevs', 'never', 'fulladd'} def clone(self, tr, destrevlog, addrevisioncb=None, - deltareuse=DELTAREUSESAMEREVS, forcedeltabothparents=None): + deltareuse=DELTAREUSESAMEREVS, forcedeltabothparents=None, + sidedatacompanion=None): """Copy this revlog to another, possibly with format changes. The destination revlog will contain the same revisions and nodes. @@ -2397,6 +2398,20 @@ In addition to the delta policy, the ``forcedeltabothparents`` argument controls whether to force compute deltas against both parents for merges. By default, the current default is used. + + If not None, the `sidedatacompanion` is callable that accept two + arguments: + + (srcrevlog, rev) + + and return a triplet that control changes to sidedata content from the + old revision to the new clone result: + + (dropall, filterout, update) + + * if `dropall` is True, all sidedata should be dropped + * `filterout` is a set of sidedata keys that should be dropped + * `update` is a mapping of additionnal/new key -> value """ if deltareuse not in self.DELTAREUSEALL: raise ValueError(_('value for deltareuse invalid: %s') % deltareuse) @@ -2429,7 +2444,7 @@ destrevlog._deltabothparents = forcedeltabothparents or oldamd self._clone(tr, destrevlog, addrevisioncb, deltareuse, - forcedeltabothparents) + forcedeltabothparents, sidedatacompanion) finally: destrevlog._lazydelta = oldlazydelta @@ -2437,7 +2452,7 @@ destrevlog._deltabothparents = oldamd def _clone(self, tr, destrevlog, addrevisioncb, deltareuse, - forcedeltabothparents): + forcedeltabothparents, sidedatacompanion): """perform the core duty of `revlog.clone` after parameter processing""" deltacomputer = deltautil.deltacomputer(destrevlog) index = self.index @@ -2452,16 +2467,30 @@ p2 = index[entry[6]][7] node = entry[7] + + sidedataactions = (False, [], {}) + if sidedatacompanion is not None: + sidedataactions = sidedatacompanion(self, rev) + # (Possibly) reuse the delta from the revlog if allowed and # the revlog chunk is a delta. cachedelta = None rawtext = None - if deltareuse == self.DELTAREUSEFULLADD: - text = self.revision(rev) + if any(sidedataactions) or deltareuse == self.DELTAREUSEFULLADD: + dropall, filterout, update = sidedataactions + text, sidedata = self._revisiondata(rev) + if dropall: + sidedata = {} + for key in filterout: + sidedata.pop(key, None) + sidedata.update(update) + if not sidedata: + sidedata = None destrevlog.addrevision(text, tr, linkrev, p1, p2, cachedelta=cachedelta, node=node, flags=flags, - deltacomputer=deltacomputer) + deltacomputer=deltacomputer, + sidedata=sidedata) else: if destrevlog._lazydelta: dp = self.deltaparent(rev)