upgrade: implement partial upgrade for upgrading persistent-nodemap
Upgrading repositories to use persistent nodemap should be fast and easy as it
requires only two things:
1) Updating the requirements
2) Writing a persistent-nodemap on disk
For both of the steps above, we don't need to edit existing revlogs.
This patch makes upgrade only do the above mentioned two steps if we are
only upgarding to use persistent-nodemap feature.
Since `nodemap.persist_nodemap()` assumes that there exists a nodemap file for
the given revlog if we are trying to call it, this patch adds `force` argument
to create a file if does not exist which is true in our upgrade case.
The test changes demonstrate that we no longer write nodemap files for manifest
after upgrade which I think is desirable.
Differential Revision: https://phab.mercurial-scm.org/D9936
--- a/mercurial/revlogutils/nodemap.py Mon Feb 01 00:10:27 2021 +0530
+++ b/mercurial/revlogutils/nodemap.py Mon Feb 01 00:02:00 2021 +0530
@@ -128,15 +128,20 @@
notr._postclose[k](None)
-def persist_nodemap(tr, revlog, pending=False):
+def persist_nodemap(tr, revlog, pending=False, force=False):
"""Write nodemap data on disk for a given revlog"""
if getattr(revlog, 'filteredrevs', ()):
raise error.ProgrammingError(
"cannot persist nodemap of a filtered changelog"
)
if revlog.nodemap_file is None:
- msg = "calling persist nodemap on a revlog without the feature enabled"
- raise error.ProgrammingError(msg)
+ if force:
+ revlog.nodemap_file = get_nodemap_file(
+ revlog.opener, revlog.indexfile
+ )
+ else:
+ msg = "calling persist nodemap on a revlog without the feature enabled"
+ raise error.ProgrammingError(msg)
can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental")
ondisk_docket = revlog._nodemap_docket
--- a/mercurial/upgrade_utils/engine.py Mon Feb 01 00:10:27 2021 +0530
+++ b/mercurial/upgrade_utils/engine.py Mon Feb 01 00:02:00 2021 +0530
@@ -24,6 +24,7 @@
util,
vfs as vfsmod,
)
+from ..revlogutils import nodemap
def _revlogfrompath(repo, path):
@@ -452,6 +453,22 @@
if upgrade_op.requirements_only:
ui.status(_(b'upgrading repository requirements\n'))
scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
+ # if there is only one action and that is persistent nodemap upgrade
+ # directly write the nodemap file and update requirements instead of going
+ # through the whole cloning process
+ elif (
+ len(upgrade_op.upgrade_actions) == 1
+ and b'persistent-nodemap' in upgrade_op._upgrade_actions_names
+ and not upgrade_op.removed_actions
+ ):
+ ui.status(
+ _(b'upgrading repository to use persistent nodemap feature\n')
+ )
+ with srcrepo.transaction(b'upgrade') as tr:
+ unfi = srcrepo.unfiltered()
+ cl = unfi.changelog
+ nodemap.persist_nodemap(tr, cl, force=True)
+ scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
else:
with dstrepo.transaction(b'upgrade') as tr:
_clonerevlogs(
--- a/tests/test-persistent-nodemap.t Mon Feb 01 00:10:27 2021 +0530
+++ b/tests/test-persistent-nodemap.t Mon Feb 01 00:02:00 2021 +0530
@@ -636,28 +636,11 @@
repository locked and read-only
creating temporary repository to stage upgraded data: $TESTTMP/test-repo/.hg/upgrade.* (glob)
(it is safe to interrupt this process any time before data migration completes)
- migrating 15018 total revisions (5006 in filelogs, 5006 in manifests, 5006 in changelog)
- migrating 1.74 MB in store; 569 MB tracked data
- migrating 5004 filelogs containing 5006 revisions (346 KB in store; 28.2 KB tracked data)
- finished migrating 5006 filelog revisions across 5004 filelogs; change in size: 0 bytes
- migrating 1 manifests containing 5006 revisions (765 KB in store; 569 MB tracked data)
- finished migrating 5006 manifest revisions across 1 manifests; change in size: 0 bytes
- migrating changelog containing 5006 revisions (673 KB in store; 363 KB tracked data)
- finished migrating 5006 changelog revisions; change in size: 0 bytes
- finished migrating 15018 total revisions; total change in store size: 0 bytes
- copying phaseroots
- data fully upgraded in a temporary repository
- marking source repository as being upgraded; clients will be unable to read from repository
- starting in-place swap of repository data
- replacing store...
- store replacement complete; repository was inconsistent for *s (glob)
- finalizing requirements file and making repository readable again
+ upgrading repository to use persistent nodemap feature
removing temporary repository $TESTTMP/test-repo/.hg/upgrade.* (glob)
$ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
00changelog-*.nd (glob)
00changelog.n
- 00manifest-*.nd (glob)
- 00manifest.n
$ hg debugnodemap --metadata
uid: * (glob)