Mercurial > hg
changeset 50363:b4b1791f36e4 stable
repo-upgrade: write new requirement before upgrading the dirstate
This will prevent a small race condition where another hg process still
believes the repo is dirstate-v1 during the upgrade process.
This is good to have, but it is not a proper fix for the underlying problem.
There is code that assumes a requirement means a usage, e.g. having the
`generaldelta` requirement would imply *all* revlogs to use general delta,
but it's not true, it simply means that the repository advertises to the
client it needs to understand `generaldelta` in order to read the repo.
In the case of the dirstate, having the requirement *technically* should always
be the same as using dirstate-v2, since there is only one dirstate and
requirements should be as minimal as possible. However, we should not assume
this and make the code more robust in a future patch (series).
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Tue, 02 May 2023 15:40:13 +0200 |
parents | 51041a1a4c59 |
children | f930af431193 |
files | mercurial/upgrade_utils/engine.py |
diffstat | 1 files changed, 10 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/upgrade_utils/engine.py Wed Apr 26 15:30:35 2023 -0400 +++ b/mercurial/upgrade_utils/engine.py Tue May 02 15:40:13 2023 +0200 @@ -655,9 +655,14 @@ pass assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2') + use_v2 = new == b'v2' + if use_v2: + # Write the requirements *before* upgrading + scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) + srcrepo.dirstate._map.preload() - srcrepo.dirstate._use_dirstate_v2 = new == b'v2' - srcrepo.dirstate._map._use_dirstate_v2 = srcrepo.dirstate._use_dirstate_v2 + srcrepo.dirstate._use_dirstate_v2 = use_v2 + srcrepo.dirstate._map._use_dirstate_v2 = use_v2 srcrepo.dirstate._dirty = True try: srcrepo.vfs.unlink(b'dirstate') @@ -667,8 +672,9 @@ pass srcrepo.dirstate.write(None) - - scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) + if not use_v2: + # Remove the v2 requirement *after* downgrading + scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add):