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