auto-upgrade: introduce a way to auto-upgrade to/from dirstate-v2
This is similar to what we introduced for `share-safe`, but apply to the
tracked-hint feature.
Differential Revision: https://phab.mercurial-scm.org/D12614
--- a/mercurial/configitems.py Tue Apr 05 05:20:05 2022 +0200
+++ b/mercurial/configitems.py Tue Mar 22 14:14:52 2022 +0100
@@ -1278,6 +1278,12 @@
)
coreconfigitem(
b'format',
+ b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
+ default=False,
+ experimental=True,
+)
+coreconfigitem(
+ b'format',
b'use-dirstate-tracked-hint',
default=False,
experimental=True,
--- a/mercurial/helptext/config.txt Tue Apr 05 05:20:05 2022 +0200
+++ b/mercurial/helptext/config.txt Tue Mar 22 14:14:52 2022 +0100
@@ -944,6 +944,24 @@
For a more comprehensive guide, see :hg:`help internals.dirstate-v2`.
+``use-dirstate-v2.automatic-upgrade-of-mismatching-repositories``
+ When enabled, an automatic upgrade will be triggered when a repository format
+ does not match its `use-dirstate-v2` config.
+
+ This is an advanced behavior that most users will not need. We recommend you
+ don't use this unless you are a seasoned administrator of a Mercurial install
+ base.
+
+ Automatic upgrade means that any process accessing the repository will
+ upgrade the repository format to use `dirstate-v2`. This only triggers if a
+ change is needed. This also applies to operations that would have been
+ read-only (like hg status).
+
+ This configuration will apply for moves in any direction, either adding the
+ `dirstate-v2` format if `format.use-dirstate-v2=yes` or removing the
+ `dirstate-v2` requirement if `format.use-dirstate-v2=no`. So we recommend
+ setting both this value and `format.use-dirstate-v2` at the same time.
+
``use-dirstate-tracked-hint``
Enable or disable the writing of "tracked key" file alongside the dirstate.
(default to disabled)
--- a/mercurial/upgrade_utils/auto_upgrade.py Tue Apr 05 05:20:05 2022 +0200
+++ b/mercurial/upgrade_utils/auto_upgrade.py Tue Mar 22 14:14:52 2022 +0100
@@ -136,7 +136,64 @@
return action
+def get_dirstate_v2_action(repo):
+ """return an automatic-upgrade action for `dirstate-v2` if applicable
+
+ If no action is needed, return None, otherwise return a callback to upgrade
+ or downgrade the repository according the configuration and repository
+ format.
+ """
+ ui = repo.ui
+ requirements = set(repo.requirements)
+ auto_upgrade_tracked_hint = ui.configbool(
+ b'format',
+ b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
+ )
+
+ action = None
+
+ if auto_upgrade_tracked_hint:
+ d2_config = ui.configbool(b'format', b'use-dirstate-v2')
+ d2_local = requirementsmod.DIRSTATE_V2_REQUIREMENT in requirements
+ if d2_config and not d2_local:
+ msg = _(
+ b"automatically upgrading repository to the `dirstate-v2`"
+ b" feature\n"
+ )
+ hint = (
+ b"(see `hg help config.format.use-dirstate-v2` for details)\n"
+ )
+
+ def action():
+ if not ui.quiet:
+ ui.write_err(msg)
+ ui.write_err(hint)
+ requirements.add(requirementsmod.DIRSTATE_V2_REQUIREMENT)
+ fake_op = AutoUpgradeOperation(requirements)
+ engine.upgrade_dirstate(repo.ui, repo, fake_op, b'v1', b'v2')
+
+ elif d2_local and not d2_config:
+ msg = _(
+ b"automatically downgrading repository from the `dirstate-v2`"
+ b" feature\n"
+ )
+ hint = (
+ b"(see `hg help config.format.use-dirstate-v2` for details)\n"
+ )
+
+ def action():
+ if not ui.quiet:
+ ui.write_err(msg)
+ ui.write_err(hint)
+ requirements.discard(requirementsmod.DIRSTATE_V2_REQUIREMENT)
+ fake_op = AutoUpgradeOperation(requirements)
+ engine.upgrade_dirstate(repo.ui, repo, fake_op, b'v2', b'v1')
+
+ return action
+
+
AUTO_UPGRADE_ACTIONS = [
+ get_dirstate_v2_action,
get_share_safe_action,
get_tracked_hint_action,
]
--- a/rust/rhg/src/main.rs Tue Apr 05 05:20:05 2022 +0200
+++ b/rust/rhg/src/main.rs Tue Mar 22 14:14:52 2022 +0100
@@ -736,6 +736,11 @@
("format", "use-dirstate-tracked-hint"),
requirements::DIRSTATE_TRACKED_HINT_V1,
),
+ (
+ ("use-dirstate-v2", "automatic-upgrade-of-mismatching-repositories"),
+ ("format", "use-dirstate-v2"),
+ requirements::DIRSTATE_V2_REQUIREMENT,
+ ),
];
/// Mercurial allows users to automatically upgrade their repository.
--- a/tests/test-help.t Tue Apr 05 05:20:05 2022 +0200
+++ b/tests/test-help.t Tue Mar 22 14:14:52 2022 +0100
@@ -1600,6 +1600,8 @@
"use-dirstate-v2"
+ "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
+
"use-dirstate-tracked-hint"
"use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
--- a/tests/test-upgrade-repo.t Tue Apr 05 05:20:05 2022 +0200
+++ b/tests/test-upgrade-repo.t Tue Mar 22 14:14:52 2022 +0100
@@ -1994,3 +1994,70 @@
dirstate-v2: no
$ cd ..
+
+Test automatic upgrade/downgrade
+================================
+
+
+For dirstate v2
+---------------
+
+create an initial repository
+
+ $ hg init auto-upgrade \
+ > --config format.use-dirstate-v2=no \
+ > --config format.use-dirstate-tracked-hint=yes \
+ > --config format.use-share-safe=no
+ $ hg debugbuilddag -R auto-upgrade --new-file .+5
+ $ hg -R auto-upgrade update
+ 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg debugformat -R auto-upgrade | grep dirstate-v2
+ dirstate-v2: no
+
+upgrade it to dirstate-v2 automatically
+
+ $ hg status -R auto-upgrade \
+ > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
+ > --config format.use-dirstate-v2=yes
+ automatically upgrading repository to the `dirstate-v2` feature
+ (see `hg help config.format.use-dirstate-v2` for details)
+ $ hg debugformat -R auto-upgrade | grep dirstate-v2
+ dirstate-v2: yes
+
+downgrade it from dirstate-v2 automatically
+
+ $ hg status -R auto-upgrade \
+ > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
+ > --config format.use-dirstate-v2=no
+ automatically downgrading repository from the `dirstate-v2` feature
+ (see `hg help config.format.use-dirstate-v2` for details)
+ $ hg debugformat -R auto-upgrade | grep dirstate-v2
+ dirstate-v2: no
+
+
+For multiple change at the same time
+------------------------------------
+
+ $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
+ dirstate-v2: no
+ tracked-hint: yes
+ share-safe: no
+
+ $ hg status -R auto-upgrade \
+ > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
+ > --config format.use-dirstate-v2=yes \
+ > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
+ > --config format.use-dirstate-tracked-hint=no\
+ > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
+ > --config format.use-share-safe=yes
+ automatically upgrading repository to the `dirstate-v2` feature
+ (see `hg help config.format.use-dirstate-v2` for details)
+ automatically upgrading repository to the `share-safe` feature
+ (see `hg help config.format.use-share-safe` for details)
+ automatically downgrading repository from the `tracked-hint` feature
+ (see `hg help config.format.use-dirstate-tracked-hint` for details)
+ $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
+ dirstate-v2: yes
+ tracked-hint: no
+ share-safe: yes
+