upgrade: prepare code (and output) for the idea of upgrading share
authorPierre-Yves David <pierre-yves.david@octobus.net>
Tue, 15 Feb 2022 23:09:07 +0100
changeset 48779 17eaeb06562c
parent 48778 c4149a110b5f
child 48780 6e77083683a7
upgrade: prepare code (and output) for the idea of upgrading share This would work for a subset of action only. Our first target is dirstate-v2. Differential Revision: https://phab.mercurial-scm.org/D12196
mercurial/upgrade.py
mercurial/upgrade_utils/actions.py
tests/test-share-safe.t
tests/test-upgrade-repo.t
--- a/mercurial/upgrade.py	Tue Feb 15 13:32:30 2022 -0500
+++ b/mercurial/upgrade.py	Tue Feb 15 23:09:07 2022 +0100
@@ -108,6 +108,22 @@
                 if not enabled:
                     touched_revlogs.discard(rl)
 
+    if repo.shared():
+        unsafe_actions = set()
+        unsafe_actions.update(up_actions)
+        unsafe_actions.update(removed_actions)
+        unsafe_actions.update(optimizations)
+        unsafe_actions = [
+            a for a in unsafe_actions if not a.compatible_with_share
+        ]
+        unsafe_actions.sort(key=lambda a: a.name)
+        if unsafe_actions:
+            m = _(b'cannot use these actions on a share repository: %s')
+            h = _(b'upgrade the main repository directly')
+            actions = b', '.join(a.name for a in unsafe_actions)
+            m %= actions
+            raise error.Abort(m, hint=h)
+
     for action in sorted(up_actions + removed_actions, key=lambda a: a.name):
         # optimisation does not "requires anything, they just needs it.
         if action.type != upgrade_actions.FORMAT_VARIANT:
--- a/mercurial/upgrade_utils/actions.py	Tue Feb 15 13:32:30 2022 -0500
+++ b/mercurial/upgrade_utils/actions.py	Tue Feb 15 23:09:07 2022 +0100
@@ -36,7 +36,10 @@
 
 
 def preservedrequirements(repo):
-    return set()
+    preserved = {
+        requirements.SHARED_REQUIREMENT,
+    }
+    return preserved & repo.requirements
 
 
 FORMAT_VARIANT = b'deficiency'
@@ -97,6 +100,9 @@
     # Whether this improvement touches the dirstate
     touches_dirstate = False
 
+    # Can this action be run on a share instead of its mains repository
+    compatible_with_share = False
+
 
 allformatvariant = []  # type: List[Type['formatvariant']]
 
@@ -899,8 +905,6 @@
         # This was a precursor to generaldelta and was never enabled by default.
         # It should (hopefully) not exist in the wild.
         b'parentdelta',
-        # Upgrade should operate on the actual store, not the shared link.
-        requirements.SHARED_REQUIREMENT,
     }
 
 
@@ -932,6 +936,16 @@
         m = _(b'cannot upgrade repository; unsupported source requirement: %s')
         blockingreqs = b', '.join(sorted(blockingreqs))
         raise error.Abort(m % blockingreqs)
+    # Upgrade should operate on the actual store, not the shared link.
+
+    bad_share = (
+        requirements.SHARED_REQUIREMENT in repo.requirements
+        and requirements.SHARESAFE_REQUIREMENT not in repo.requirements
+    )
+    if bad_share:
+        m = _(b'cannot upgrade repository; share repository without share-safe')
+        h = _(b'check :hg:`help config.format.use-share-safe`')
+        raise error.Abort(m, hint=h)
 
 
 ### Verify the validity of the planned requirement changes ####################
@@ -972,18 +986,19 @@
     Extensions should monkeypatch this to add their custom requirements.
     """
     supported = {
+        requirements.CHANGELOGV2_REQUIREMENT,
+        requirements.COPIESSDC_REQUIREMENT,
+        requirements.DIRSTATE_V2_REQUIREMENT,
         requirements.DOTENCODE_REQUIREMENT,
         requirements.FNCACHE_REQUIREMENT,
         requirements.GENERALDELTA_REQUIREMENT,
+        requirements.NODEMAP_REQUIREMENT,
         requirements.REVLOGV1_REQUIREMENT,  # allowed in case of downgrade
-        requirements.STORE_REQUIREMENT,
+        requirements.REVLOGV2_REQUIREMENT,
+        requirements.SHARED_REQUIREMENT,
+        requirements.SHARESAFE_REQUIREMENT,
         requirements.SPARSEREVLOG_REQUIREMENT,
-        requirements.COPIESSDC_REQUIREMENT,
-        requirements.NODEMAP_REQUIREMENT,
-        requirements.SHARESAFE_REQUIREMENT,
-        requirements.REVLOGV2_REQUIREMENT,
-        requirements.CHANGELOGV2_REQUIREMENT,
-        requirements.DIRSTATE_V2_REQUIREMENT,
+        requirements.STORE_REQUIREMENT,
     }
     for name in compression.compengines:
         engine = compression.compengines[name]
--- a/tests/test-share-safe.t	Tue Feb 15 13:32:30 2022 -0500
+++ b/tests/test-share-safe.t	Tue Feb 15 23:09:07 2022 +0100
@@ -244,7 +244,8 @@
   $ echo "use-persistent-nodemap=True" >> .hg/hgrc
 
   $ hg debugupgraderepo --run -q -R ../shared1
-  abort: cannot upgrade repository; unsupported source requirement: shared
+  abort: cannot use these actions on a share repository: persistent-nodemap
+  (upgrade the main repository directly)
   [255]
 
   $ hg debugupgraderepo --run -q
--- a/tests/test-upgrade-repo.t	Tue Feb 15 13:32:30 2022 -0500
+++ b/tests/test-upgrade-repo.t	Tue Feb 15 23:09:07 2022 +0100
@@ -32,10 +32,12 @@
   $ hg init share-parent
   $ hg -q share share-parent share-child
 
-  $ hg -R share-child debugupgraderepo
-  abort: cannot upgrade repository; unsupported source requirement: shared
+  $ hg -R share-child debugupgraderepo --config format.sparse-revlog=no
+  abort: cannot use these actions on a share repository: sparserevlog
+  (upgrade the main repository directly)
   [255]
 
+
 Do not yet support upgrading treemanifest repos
 
   $ hg --config experimental.treemanifest=true init treemanifest