Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/upgrade_utils/engine.py @ 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 | 1994842955db |
children | 521fec115dad |
comparison
equal
deleted
inserted
replaced
50362:51041a1a4c59 | 50363:b4b1791f36e4 |
---|---|
653 # The dirstate does not exist on an empty repo or a repo with no | 653 # The dirstate does not exist on an empty repo or a repo with no |
654 # revision checked out | 654 # revision checked out |
655 pass | 655 pass |
656 | 656 |
657 assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2') | 657 assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2') |
658 use_v2 = new == b'v2' | |
659 if use_v2: | |
660 # Write the requirements *before* upgrading | |
661 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) | |
662 | |
658 srcrepo.dirstate._map.preload() | 663 srcrepo.dirstate._map.preload() |
659 srcrepo.dirstate._use_dirstate_v2 = new == b'v2' | 664 srcrepo.dirstate._use_dirstate_v2 = use_v2 |
660 srcrepo.dirstate._map._use_dirstate_v2 = srcrepo.dirstate._use_dirstate_v2 | 665 srcrepo.dirstate._map._use_dirstate_v2 = use_v2 |
661 srcrepo.dirstate._dirty = True | 666 srcrepo.dirstate._dirty = True |
662 try: | 667 try: |
663 srcrepo.vfs.unlink(b'dirstate') | 668 srcrepo.vfs.unlink(b'dirstate') |
664 except FileNotFoundError: | 669 except FileNotFoundError: |
665 # The dirstate does not exist on an empty repo or a repo with no | 670 # The dirstate does not exist on an empty repo or a repo with no |
666 # revision checked out | 671 # revision checked out |
667 pass | 672 pass |
668 | 673 |
669 srcrepo.dirstate.write(None) | 674 srcrepo.dirstate.write(None) |
670 | 675 if not use_v2: |
671 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) | 676 # Remove the v2 requirement *after* downgrading |
677 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) | |
672 | 678 |
673 | 679 |
674 def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add): | 680 def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add): |
675 if add: | 681 if add: |
676 srcrepo.dirstate._use_tracked_hint = True | 682 srcrepo.dirstate._use_tracked_hint = True |