diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -2353,7 +2353,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.
@@ -2394,6 +2395,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)
@@ -2426,7 +2441,7 @@
             destrevlog._deltabothparents = forcedeltabothparents or oldamd
 
             self._clone(tr, destrevlog, addrevisioncb, deltareuse,
-                        forcedeltabothparents)
+                        forcedeltabothparents, sidedatacompanion)
 
         finally:
             destrevlog._lazydelta = oldlazydelta
@@ -2434,7 +2449,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
@@ -2449,16 +2464,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)