changeset 46576:67b5fafd3a46

upgrade: speed up when we have only nodemap to downgrade Similar to what we do on upgrade, if we have only persistent-nodemap to downgrade we will just delete the nodemap files and update repository requirements instead of processing all the revlogs. After downgrade, we are left with unrequired docket and transaction files which seems fine but can work on deleting them if someone feels we should. Differential Revision: https://phab.mercurial-scm.org/D9992
author Pulkit Goyal <7895pulkit@gmail.com>
date Wed, 10 Feb 2021 17:08:34 +0530
parents 636853347e14
children 018d622e814d
files mercurial/revlogutils/nodemap.py mercurial/upgrade_utils/engine.py tests/test-persistent-nodemap.t
diffstat 3 files changed, 42 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revlogutils/nodemap.py	Mon Feb 15 15:13:20 2021 +0530
+++ b/mercurial/revlogutils/nodemap.py	Wed Feb 10 17:08:34 2021 +0530
@@ -128,6 +128,14 @@
         notr._postclose[k](None)
 
 
+def delete_nodemap(tr, repo, revlog):
+    """ Delete nodemap data on disk for a given revlog"""
+    if revlog.nodemap_file is None:
+        msg = "calling persist nodemap on a revlog without the feature enabled"
+        raise error.ProgrammingError(msg)
+    repo.svfs.unlink(revlog.nodemap_file)
+
+
 def persist_nodemap(tr, revlog, pending=False, force=False):
     """Write nodemap data on disk for a given revlog"""
     if getattr(revlog, 'filteredrevs', ()):
--- a/mercurial/upgrade_utils/engine.py	Mon Feb 15 15:13:20 2021 +0530
+++ b/mercurial/upgrade_utils/engine.py	Wed Feb 10 17:08:34 2021 +0530
@@ -476,6 +476,27 @@
                 tr, unfi.manifestlog._rootstore._revlog, force=True
             )
         scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
+    elif (
+        len(upgrade_op.removed_actions) == 1
+        and [
+            x
+            for x in upgrade_op.removed_actions
+            if x.name == b'persistent-nodemap'
+        ]
+        and not upgrade_op.upgrade_actions
+    ):
+        ui.status(
+            _(b'downgrading repository to not use persistent nodemap feature\n')
+        )
+        with srcrepo.transaction(b'upgrade') as tr:
+            unfi = srcrepo.unfiltered()
+            cl = unfi.changelog
+            nodemap.delete_nodemap(tr, srcrepo, cl)
+            # check comment 20 lines above for accessing private attributes
+            nodemap.delete_nodemap(
+                tr, srcrepo, unfi.manifestlog._rootstore._revlog
+            )
+        scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
     else:
         with dstrepo.transaction(b'upgrade') as tr:
             _clonerevlogs(
--- a/tests/test-persistent-nodemap.t	Mon Feb 15 15:13:20 2021 +0530
+++ b/tests/test-persistent-nodemap.t	Wed Feb 10 17:08:34 2021 +0530
@@ -581,7 +581,7 @@
   plain-cl-delta:     yes    yes     yes
   compression:        zlib   zlib    zlib
   compression-level:  default default default
-  $ hg debugupgraderepo --run --no-backup --quiet
+  $ hg debugupgraderepo --run --no-backup
   upgrade will perform the following actions:
   
   requirements
@@ -593,8 +593,17 @@
     - changelog
     - manifest
   
+  beginning upgrade...
+  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)
+  downgrading repository to not use persistent nodemap feature
+  removing temporary repository $TESTTMP/test-repo/.hg/upgrade.* (glob)
   $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
-  [1]
+  00changelog-*.nd (glob)
+  00manifest-*.nd (glob)
+  undo.backup.00changelog.n
+  undo.backup.00manifest.n
   $ hg debugnodemap --metadata
 
 
@@ -643,6 +652,8 @@
   00changelog.n
   00manifest-*.nd (glob)
   00manifest.n
+  undo.backup.00changelog.n
+  undo.backup.00manifest.n
 
   $ hg debugnodemap --metadata
   uid: * (glob)