diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1278,6 +1278,12 @@ coreconfigitem( ) 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, diff --git a/mercurial/helptext/config.txt b/mercurial/helptext/config.txt --- a/mercurial/helptext/config.txt +++ b/mercurial/helptext/config.txt @@ -944,6 +944,24 @@ https://www.mercurial-scm.org/wiki/Missi 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) diff --git a/mercurial/upgrade_utils/auto_upgrade.py b/mercurial/upgrade_utils/auto_upgrade.py --- a/mercurial/upgrade_utils/auto_upgrade.py +++ b/mercurial/upgrade_utils/auto_upgrade.py @@ -136,7 +136,64 @@ def get_tracked_hint_action(repo): 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, ] diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs +++ b/rust/rhg/src/main.rs @@ -736,6 +736,11 @@ const AUTO_UPGRADES: &[((&str, &str), (& ("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. diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1600,6 +1600,8 @@ Separate sections from subsections "use-dirstate-v2" + "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories" + "use-dirstate-tracked-hint" "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories" 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 @@ -1994,3 +1994,70 @@ downgrade 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 +