Patchwork D6942: upgrade: allow upgrade to repository using sidedata

login
register
mail settings
Submitter phabricator
Date Oct. 1, 2019, 4:08 p.m.
Message ID <differential-rev-PHID-DREV-anwafwdly4njjhudxecw-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/41896/
State Superseded
Headers show

Comments

phabricator - Oct. 1, 2019, 4:08 p.m.
marmoute created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Repository can now be migrated to support sidedata. More requirements and
  migration will be needed to actual side-data usage. This is a step in that
  direction.
  
  To test the feature, we leverage the test extension. It make sure the `update`
  part of the side-data migration actually works.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/upgrade.py
  tests/test-sidedata.t
  tests/test-upgrade-repo.t
  tests/testlib/ext-sidedata.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mjpieters, mercurial-devel

Patch

diff --git a/tests/testlib/ext-sidedata.py b/tests/testlib/ext-sidedata.py
--- a/tests/testlib/ext-sidedata.py
+++ b/tests/testlib/ext-sidedata.py
@@ -12,8 +12,10 @@ 
 
 from mercurial import (
     extensions,
+    localrepo,
     node,
     revlog,
+    upgrade,
 )
 
 from mercurial.revlogutils import (
@@ -35,6 +37,8 @@ 
 
 def wraprevision(orig, self, nodeorrev, *args, **kwargs):
     text = orig(self, nodeorrev, *args, **kwargs)
+    if getattr(self, 'sidedatanocheck', False):
+        return text
     if nodeorrev != node.nullrev and nodeorrev != node.nullid:
         sd = self.sidedata(nodeorrev)
         if len(text) != struct.unpack('>I', sd[sidedata.SD_TEST1])[0]:
@@ -45,6 +49,28 @@ 
             raise RuntimeError('sha256 mismatch')
     return text
 
+def wrapgetsidedatacompanion(orig, srcrepo, dstrepo):
+    assert orig(srcrepo, dstrepo) is None # deal with composition later
+    if (not localrepo.SIDEDATA_REQUIREMENT in srcrepo.requirements
+        and localrepo.SIDEDATA_REQUIREMENT in dstrepo.requirements):
+        def getsidedatacompanion(revlog, rev):
+            update = {}
+            revlog.sidedatanocheck = True
+            try:
+                text = revlog.revision(rev)
+            finally:
+                del revlog.sidedatanocheck
+            ## let's store some arbitrary data just for testing
+            # text length
+            update[sidedata.SD_TEST1] = struct.pack('>I', len(text))
+            # and sha2 hashes
+            sha256 = hashlib.sha256(text).digest()
+            update[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
+            return False, (), update
+    return getsidedatacompanion
+
 def extsetup(ui):
     extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
     extensions.wrapfunction(revlog.revlog, 'revision', wraprevision)
+    extensions.wrapfunction(upgrade, 'getsidedatacompanion',
+                            wrapgetsidedatacompanion)
diff --git a/tests/test-upgrade-repo.t b/tests/test-upgrade-repo.t
--- a/tests/test-upgrade-repo.t
+++ b/tests/test-upgrade-repo.t
@@ -1328,6 +1328,35 @@ 
   sparserevlog
   store
 
-  $ cd ..
+#endif
+
+Check upgrading to a side-data revlog
+-------------------------------------
+
+upgrade
 
-#endif
+  $ hg --config format.use-side-data=yes debugupgraderepo --run  --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" >/dev/null
+  $ hg debugformat -v
+  format-variant    repo config default
+  fncache:           yes    yes     yes
+  dotencode:         yes    yes     yes
+  generaldelta:      yes    yes     yes
+  sparserevlog:      yes    yes     yes
+  sidedata:          yes     no      no
+  plain-cl-delta:    yes    yes     yes
+  compression:       zstd   zstd    zlib
+  compression-level: default default default
+  $ cat .hg/requires
+  dotencode
+  exp-sidedata-flag
+  fncache
+  generaldelta
+  revlog-compression-zstd
+  revlogv1
+  sparserevlog
+  store
+  $ hg debugsidedata -c 0
+  2 sidedata entries
+   entry-0001 size 4
+   entry-0002 size 32
+
diff --git a/tests/test-sidedata.t b/tests/test-sidedata.t
--- a/tests/test-sidedata.t
+++ b/tests/test-sidedata.t
@@ -45,8 +45,8 @@ 
 
 Right now, sidedata has not upgrade support
 
-Check that we cannot upgrade to sidedata
-----------------------------------------
+Check that we can upgrade to sidedata
+-------------------------------------
 
   $ hg init up-no-side-data --config format.use-side-data=no
   $ hg debugformat -v -R up-no-side-data
@@ -69,9 +69,7 @@ 
   plain-cl-delta:    yes    yes     yes
   compression:       zlib   zlib    zlib
   compression-level: default default default
-  $ hg debugupgraderepo -R up-no-side-data --config format.use-side-data=yes
-  abort: cannot upgrade repository; do not support adding requirement: exp-sidedata-flag
-  [255]
+  $ hg debugupgraderepo -R up-no-side-data --config format.use-side-data=yes > /dev/null
 
 Check that we cannot upgrade to sidedata
 ----------------------------------------
diff --git a/mercurial/upgrade.py b/mercurial/upgrade.py
--- a/mercurial/upgrade.py
+++ b/mercurial/upgrade.py
@@ -32,6 +32,7 @@ 
 RECLONES_REQUIREMENTS = {
     'generaldelta',
     localrepo.SPARSEREVLOG_REQUIREMENT,
+    localrepo.SIDEDATA_REQUIREMENT,
 }
 
 def requiredsourcerequirements(repo):
@@ -97,6 +98,7 @@ 
         'revlogv1',
         'store',
         localrepo.SPARSEREVLOG_REQUIREMENT,
+        localrepo.SIDEDATA_REQUIREMENT,
     }
     for name in compression.compengines:
         engine = compression.compengines[name]
@@ -121,6 +123,7 @@ 
         'fncache',
         'generaldelta',
         localrepo.SPARSEREVLOG_REQUIREMENT,
+        localrepo.SIDEDATA_REQUIREMENT,
     }
     for name in compression.compengines:
         engine = compression.compengines[name]
@@ -592,6 +595,9 @@ 
                                  UPGRADE_MANIFEST,
                                  UPGRADE_FILELOG])
 
+def getsidedatacompanion(srcrepo, destrepo):
+    return None
+
 def matchrevlog(revlogfilter, entry):
     """check is a revlog is selected for cloning
 
@@ -676,6 +682,8 @@ 
     def oncopiedrevision(rl, rev, node):
         progress.increment()
 
+    sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
+
     # Do the actual copying.
     # FUTURE this operation can be farmed off to worker processes.
     seen = set()
@@ -728,7 +736,8 @@ 
             newrl = _revlogfrompath(dstrepo, unencoded)
             oldrl.clone(tr, newrl, addrevisioncb=oncopiedrevision,
                         deltareuse=deltareuse,
-                        forcedeltabothparents=forcedeltabothparents)
+                        forcedeltabothparents=forcedeltabothparents,
+                        sidedatacompanion=sidedatacompanion)
         else:
             msg = _('blindly copying %s containing %i revisions\n')
             ui.note(msg % (unencoded, len(oldrl)))