comparison mercurial/upgrade_utils/engine.py @ 47328:a43d256c041a

dirstate-v2: Add `hg debugupgraderepo` command support This command changes changes the file formats used inside an existing repository to what they would be in a new repository with the current config. For example: hg debugupgraderepo --config format.exp-dirstate-v2=1 --run hg debugupgraderepo --config format.exp-dirstate-v2=0 --run If a repository has a dirstate in v1 format, the first command would upgrade it to dirstate-v2. Conversely, if a repository has a dirstate in v2 format, the second command would downgrade it to v1. (Both may also run some unrelated upgrades.) Since `format.exp-dirstate-v2` is currently disabled by default, not specifying it in `--config` or any configuration file would result in the second command. Differential Revision: https://phab.mercurial-scm.org/D10769
author Simon Sapin <simon.sapin@octobus.net>
date Wed, 19 May 2021 18:35:43 +0200
parents 396442cd7e6a
children f030c7d22032
comparison
equal deleted inserted replaced
47327:e985a36c2aa3 47328:a43d256c041a
28 constants as revlogconst, 28 constants as revlogconst,
29 flagutil, 29 flagutil,
30 nodemap, 30 nodemap,
31 sidedata as sidedatamod, 31 sidedata as sidedatamod,
32 ) 32 )
33 from . import actions as upgrade_actions
33 34
34 35
35 def get_sidedata_helpers(srcrepo, dstrepo): 36 def get_sidedata_helpers(srcrepo, dstrepo):
36 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade') 37 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
37 sequential = pycompat.iswindows or not use_w 38 sequential = pycompat.iswindows or not use_w
456 b'(it is safe to interrupt this process any time before ' 457 b'(it is safe to interrupt this process any time before '
457 b'data migration completes)\n' 458 b'data migration completes)\n'
458 ) 459 )
459 ) 460 )
460 461
462 if upgrade_actions.dirstatev2 in upgrade_op.upgrade_actions:
463 ui.status(_(b'upgrading to dirstate-v2 from v1\n'))
464 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v1', b'v2')
465 upgrade_op.upgrade_actions.remove(upgrade_actions.dirstatev2)
466
467 if upgrade_actions.dirstatev2 in upgrade_op.removed_actions:
468 ui.status(_(b'downgrading from dirstate-v2 to v1\n'))
469 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v2', b'v1')
470 upgrade_op.removed_actions.remove(upgrade_actions.dirstatev2)
471
472 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
473 return
474
461 if upgrade_op.requirements_only: 475 if upgrade_op.requirements_only:
462 ui.status(_(b'upgrading repository requirements\n')) 476 ui.status(_(b'upgrading repository requirements\n'))
463 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements) 477 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
464 # if there is only one action and that is persistent nodemap upgrade 478 # if there is only one action and that is persistent nodemap upgrade
465 # directly write the nodemap file and update requirements instead of going 479 # directly write the nodemap file and update requirements instead of going
466 # through the whole cloning process 480 # through the whole cloning process
467 elif ( 481 elif (
468 len(upgrade_op.upgrade_actions) == 1 482 len(upgrade_op.upgrade_actions) == 1
469 and b'persistent-nodemap' in upgrade_op._upgrade_actions_names 483 and b'persistent-nodemap' in upgrade_op.upgrade_actions_names
470 and not upgrade_op.removed_actions 484 and not upgrade_op.removed_actions
471 ): 485 ):
472 ui.status( 486 ui.status(
473 _(b'upgrading repository to use persistent nodemap feature\n') 487 _(b'upgrading repository to use persistent nodemap feature\n')
474 ) 488 )
589 # location. This is simpler. 603 # location. This is simpler.
590 assert backupvfs is not None # help pytype 604 assert backupvfs is not None # help pytype
591 backupvfs.unlink(b'store/lock') 605 backupvfs.unlink(b'store/lock')
592 606
593 return backuppath 607 return backuppath
608
609
610 def upgrade_dirstate(ui, srcrepo, upgrade_op, old, new):
611 if upgrade_op.backup_store:
612 backuppath = pycompat.mkdtemp(
613 prefix=b'upgradebackup.', dir=srcrepo.path
614 )
615 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
616 backupvfs = vfsmod.vfs(backuppath)
617 util.copyfile(
618 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
619 )
620 util.copyfile(
621 srcrepo.vfs.join(b'dirstate'), backupvfs.join(b'dirstate')
622 )
623
624 assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2')
625 srcrepo.dirstate._map._use_dirstate_tree = True
626 srcrepo.dirstate._map.preload()
627 srcrepo.dirstate._use_dirstate_v2 = new == b'v2'
628 srcrepo.dirstate._map._use_dirstate_v2 = srcrepo.dirstate._use_dirstate_v2
629 srcrepo.dirstate._dirty = True
630 srcrepo.dirstate.write(None)
631
632 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)