revlog: add a way to control sidedata changes during revlog.clone
authorPierre-Yves David <pierre-yves.david@octobus.net>
Sun, 06 Oct 2019 23:36:51 -0400
changeset 43133 3de4d13f22be
parent 43132 8f807a83d53b
child 43134 75ad8af9c95e
revlog: add a way to control sidedata changes during revlog.clone We introduce a new argument to pass a callable dealing with the side data logic. Since the side data are usually associated to higher level logic, the revlog code itself is unlikely to know that to do itself. As a result the higher level upgrade code will be responsible to decide what needs to changes. The lower level revlog.clone just get simple instructions to apply. Differential Revision: https://phab.mercurial-scm.org/D6941
mercurial/revlog.py
--- a/mercurial/revlog.py	Sun Oct 06 23:36:51 2019 -0400
+++ b/mercurial/revlog.py	Sun Oct 06 23:36:51 2019 -0400
@@ -2542,6 +2542,7 @@
         addrevisioncb=None,
         deltareuse=DELTAREUSESAMEREVS,
         forcedeltabothparents=None,
+        sidedatacompanion=None,
     ):
         """Copy this revlog to another, possibly with format changes.
 
@@ -2583,6 +2584,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(
@@ -2617,7 +2632,12 @@
             destrevlog._deltabothparents = forcedeltabothparents or oldamd
 
             self._clone(
-                tr, destrevlog, addrevisioncb, deltareuse, forcedeltabothparents
+                tr,
+                destrevlog,
+                addrevisioncb,
+                deltareuse,
+                forcedeltabothparents,
+                sidedatacompanion,
             )
 
         finally:
@@ -2626,7 +2646,13 @@
             destrevlog._deltabothparents = oldamd
 
     def _clone(
-        self, tr, destrevlog, addrevisioncb, deltareuse, forcedeltabothparents
+        self,
+        tr,
+        destrevlog,
+        addrevisioncb,
+        deltareuse,
+        forcedeltabothparents,
+        sidedatacompanion,
     ):
         """perform the core duty of `revlog.clone` after parameter processing"""
         deltacomputer = deltautil.deltacomputer(destrevlog)
@@ -2642,12 +2668,24 @@
             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,
@@ -2658,6 +2696,7 @@
                     node=node,
                     flags=flags,
                     deltacomputer=deltacomputer,
+                    sidedata=sidedata,
                 )
             else:
                 if destrevlog._lazydelta: