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))) 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/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/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,29 @@ raise RuntimeError('sha256 mismatch') return text +def wrapgetsidedatacompanion(orig, srcrepo, dstrepo): + sidedatacompanion = orig(srcrepo, dstrepo) + addedreqs = dstrepo.requirements - srcrepo.requirements + if (localrepo.SIDEDATA_REQUIREMENT in addedreqs): + assert sidedatacompanion is None # deal with composition later + def sidedatacompanion(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 sidedatacompanion + def extsetup(ui): extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision) extensions.wrapfunction(revlog.revlog, 'revision', wraprevision) + extensions.wrapfunction(upgrade, 'getsidedatacompanion', + wrapgetsidedatacompanion)