Mercurial > public > mercurial-scm > hg
comparison mercurial/upgrade_utils/actions.py @ 47320: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 | e985a36c2aa3 |
children | 4259a72fe528 |
comparison
equal
deleted
inserted
replaced
47319:e985a36c2aa3 | 47320:a43d256c041a |
---|---|
78 | 78 |
79 # Message intended for humans which will be shown post an upgrade | 79 # Message intended for humans which will be shown post an upgrade |
80 # operation in which this improvement was removed | 80 # operation in which this improvement was removed |
81 postdowngrademessage = None | 81 postdowngrademessage = None |
82 | 82 |
83 # By default for now, we assume every improvement touches all the things | 83 # By default we assume that every improvement touches requirements and all revlogs |
84 | 84 |
85 # Whether this improvement touches filelogs | 85 # Whether this improvement touches filelogs |
86 touches_filelogs = True | 86 touches_filelogs = True |
87 | 87 |
88 # Whether this improvement touches manifests | 88 # Whether this improvement touches manifests |
91 # Whether this improvement touches changelog | 91 # Whether this improvement touches changelog |
92 touches_changelog = True | 92 touches_changelog = True |
93 | 93 |
94 # Whether this improvement changes repository requirements | 94 # Whether this improvement changes repository requirements |
95 touches_requirements = True | 95 touches_requirements = True |
96 | |
97 # Whether this improvement touches the dirstate | |
98 touches_dirstate = False | |
96 | 99 |
97 | 100 |
98 allformatvariant = [] # type: List[Type['formatvariant']] | 101 allformatvariant = [] # type: List[Type['formatvariant']] |
99 | 102 |
100 | 103 |
162 upgrademessage = _( | 165 upgrademessage = _( |
163 b'repository will be more resilient to storing ' | 166 b'repository will be more resilient to storing ' |
164 b'certain paths and performance of certain ' | 167 b'certain paths and performance of certain ' |
165 b'operations should be improved' | 168 b'operations should be improved' |
166 ) | 169 ) |
170 | |
171 | |
172 @registerformatvariant | |
173 class dirstatev2(requirementformatvariant): | |
174 name = b'dirstate-v2' | |
175 _requirement = requirements.DIRSTATE_V2_REQUIREMENT | |
176 | |
177 default = False | |
178 | |
179 description = _( | |
180 b'version 1 of the dirstate file format requires ' | |
181 b'reading and parsing it all at once.' | |
182 ) | |
183 | |
184 upgrademessage = _(b'"hg status" will be faster') | |
185 | |
186 touches_filelogs = False | |
187 touches_manifests = False | |
188 touches_changelog = False | |
189 touches_requirements = True | |
190 touches_dirstate = True | |
167 | 191 |
168 | 192 |
169 @registerformatvariant | 193 @registerformatvariant |
170 class dotencode(requirementformatvariant): | 194 class dotencode(requirementformatvariant): |
171 name = b'dotencode' | 195 name = b'dotencode' |
642 self.ui = ui | 666 self.ui = ui |
643 self.new_requirements = new_requirements | 667 self.new_requirements = new_requirements |
644 self.current_requirements = current_requirements | 668 self.current_requirements = current_requirements |
645 # list of upgrade actions the operation will perform | 669 # list of upgrade actions the operation will perform |
646 self.upgrade_actions = upgrade_actions | 670 self.upgrade_actions = upgrade_actions |
647 self._upgrade_actions_names = set([a.name for a in upgrade_actions]) | |
648 self.removed_actions = removed_actions | 671 self.removed_actions = removed_actions |
649 self.revlogs_to_process = revlogs_to_process | 672 self.revlogs_to_process = revlogs_to_process |
650 # requirements which will be added by the operation | 673 # requirements which will be added by the operation |
651 self._added_requirements = ( | 674 self._added_requirements = ( |
652 self.new_requirements - self.current_requirements | 675 self.new_requirements - self.current_requirements |
665 self.unused_optimizations = [ | 688 self.unused_optimizations = [ |
666 i for i in all_optimizations if i not in self.upgrade_actions | 689 i for i in all_optimizations if i not in self.upgrade_actions |
667 ] | 690 ] |
668 | 691 |
669 # delta reuse mode of this upgrade operation | 692 # delta reuse mode of this upgrade operation |
693 upgrade_actions_names = self.upgrade_actions_names | |
670 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS | 694 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS |
671 if b're-delta-all' in self._upgrade_actions_names: | 695 if b're-delta-all' in upgrade_actions_names: |
672 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER | 696 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER |
673 elif b're-delta-parent' in self._upgrade_actions_names: | 697 elif b're-delta-parent' in upgrade_actions_names: |
674 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS | 698 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS |
675 elif b're-delta-multibase' in self._upgrade_actions_names: | 699 elif b're-delta-multibase' in upgrade_actions_names: |
676 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS | 700 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS |
677 elif b're-delta-fulladd' in self._upgrade_actions_names: | 701 elif b're-delta-fulladd' in upgrade_actions_names: |
678 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD | 702 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD |
679 | 703 |
680 # should this operation force re-delta of both parents | 704 # should this operation force re-delta of both parents |
681 self.force_re_delta_both_parents = ( | 705 self.force_re_delta_both_parents = ( |
682 b're-delta-multibase' in self._upgrade_actions_names | 706 b're-delta-multibase' in upgrade_actions_names |
683 ) | 707 ) |
684 | 708 |
685 # should this operation create a backup of the store | 709 # should this operation create a backup of the store |
686 self.backup_store = backup_store | 710 self.backup_store = backup_store |
687 | 711 |
688 # whether the operation touches different revlogs at all or not | 712 @property |
689 self.touches_filelogs = self._touches_filelogs() | 713 def upgrade_actions_names(self): |
690 self.touches_manifests = self._touches_manifests() | 714 return set([a.name for a in self.upgrade_actions]) |
691 self.touches_changelog = self._touches_changelog() | 715 |
692 # whether the operation touches requirements file or not | 716 @property |
693 self.touches_requirements = self._touches_requirements() | 717 def requirements_only(self): |
694 self.touches_store = ( | 718 # does the operation only touches repository requirement |
695 self.touches_filelogs | 719 return ( |
696 or self.touches_manifests | 720 self.touches_requirements |
697 or self.touches_changelog | 721 and not self.touches_filelogs |
722 and not self.touches_manifests | |
723 and not self.touches_changelog | |
724 and not self.touches_dirstate | |
698 ) | 725 ) |
699 # does the operation only touches repository requirement | 726 |
700 self.requirements_only = ( | 727 @property |
701 self.touches_requirements and not self.touches_store | 728 def touches_filelogs(self): |
702 ) | |
703 | |
704 def _touches_filelogs(self): | |
705 for a in self.upgrade_actions: | 729 for a in self.upgrade_actions: |
706 # in optimisations, we re-process the revlogs again | 730 # in optimisations, we re-process the revlogs again |
707 if a.type == OPTIMISATION: | 731 if a.type == OPTIMISATION: |
708 return True | 732 return True |
709 elif a.touches_filelogs: | 733 elif a.touches_filelogs: |
711 for a in self.removed_actions: | 735 for a in self.removed_actions: |
712 if a.touches_filelogs: | 736 if a.touches_filelogs: |
713 return True | 737 return True |
714 return False | 738 return False |
715 | 739 |
716 def _touches_manifests(self): | 740 @property |
741 def touches_manifests(self): | |
717 for a in self.upgrade_actions: | 742 for a in self.upgrade_actions: |
718 # in optimisations, we re-process the revlogs again | 743 # in optimisations, we re-process the revlogs again |
719 if a.type == OPTIMISATION: | 744 if a.type == OPTIMISATION: |
720 return True | 745 return True |
721 elif a.touches_manifests: | 746 elif a.touches_manifests: |
723 for a in self.removed_actions: | 748 for a in self.removed_actions: |
724 if a.touches_manifests: | 749 if a.touches_manifests: |
725 return True | 750 return True |
726 return False | 751 return False |
727 | 752 |
728 def _touches_changelog(self): | 753 @property |
754 def touches_changelog(self): | |
729 for a in self.upgrade_actions: | 755 for a in self.upgrade_actions: |
730 # in optimisations, we re-process the revlogs again | 756 # in optimisations, we re-process the revlogs again |
731 if a.type == OPTIMISATION: | 757 if a.type == OPTIMISATION: |
732 return True | 758 return True |
733 elif a.touches_changelog: | 759 elif a.touches_changelog: |
735 for a in self.removed_actions: | 761 for a in self.removed_actions: |
736 if a.touches_changelog: | 762 if a.touches_changelog: |
737 return True | 763 return True |
738 return False | 764 return False |
739 | 765 |
740 def _touches_requirements(self): | 766 @property |
767 def touches_requirements(self): | |
741 for a in self.upgrade_actions: | 768 for a in self.upgrade_actions: |
742 # optimisations are used to re-process revlogs and does not result | 769 # optimisations are used to re-process revlogs and does not result |
743 # in a requirement being added or removed | 770 # in a requirement being added or removed |
744 if a.type == OPTIMISATION: | 771 if a.type == OPTIMISATION: |
745 pass | 772 pass |
746 elif a.touches_requirements: | 773 elif a.touches_requirements: |
747 return True | 774 return True |
748 for a in self.removed_actions: | 775 for a in self.removed_actions: |
749 if a.touches_requirements: | 776 if a.touches_requirements: |
777 return True | |
778 | |
779 @property | |
780 def touches_dirstate(self): | |
781 for a in self.upgrade_actions: | |
782 # revlog optimisations do not affect the dirstate | |
783 if a.type == OPTIMISATION: | |
784 pass | |
785 elif a.touches_dirstate: | |
786 return True | |
787 for a in self.removed_actions: | |
788 if a.touches_dirstate: | |
750 return True | 789 return True |
751 | 790 |
752 return False | 791 return False |
753 | 792 |
754 def _write_labeled(self, l, label): | 793 def _write_labeled(self, l, label): |
906 requirements.NODEMAP_REQUIREMENT, | 945 requirements.NODEMAP_REQUIREMENT, |
907 requirements.SHARESAFE_REQUIREMENT, | 946 requirements.SHARESAFE_REQUIREMENT, |
908 requirements.REVLOGV2_REQUIREMENT, | 947 requirements.REVLOGV2_REQUIREMENT, |
909 requirements.CHANGELOGV2_REQUIREMENT, | 948 requirements.CHANGELOGV2_REQUIREMENT, |
910 requirements.REVLOGV1_REQUIREMENT, | 949 requirements.REVLOGV1_REQUIREMENT, |
950 requirements.DIRSTATE_V2_REQUIREMENT, | |
911 } | 951 } |
912 for name in compression.compengines: | 952 for name in compression.compengines: |
913 engine = compression.compengines[name] | 953 engine = compression.compengines[name] |
914 if engine.available() and engine.revlogheader(): | 954 if engine.available() and engine.revlogheader(): |
915 supported.add(b'exp-compression-%s' % name) | 955 supported.add(b'exp-compression-%s' % name) |
968 requirements.NODEMAP_REQUIREMENT, | 1008 requirements.NODEMAP_REQUIREMENT, |
969 requirements.SHARESAFE_REQUIREMENT, | 1009 requirements.SHARESAFE_REQUIREMENT, |
970 requirements.REVLOGV1_REQUIREMENT, | 1010 requirements.REVLOGV1_REQUIREMENT, |
971 requirements.REVLOGV2_REQUIREMENT, | 1011 requirements.REVLOGV2_REQUIREMENT, |
972 requirements.CHANGELOGV2_REQUIREMENT, | 1012 requirements.CHANGELOGV2_REQUIREMENT, |
1013 requirements.DIRSTATE_V2_REQUIREMENT, | |
973 } | 1014 } |
974 for name in compression.compengines: | 1015 for name in compression.compengines: |
975 engine = compression.compengines[name] | 1016 engine = compression.compengines[name] |
976 if engine.available() and engine.revlogheader(): | 1017 if engine.available() and engine.revlogheader(): |
977 supported.add(b'exp-compression-%s' % name) | 1018 supported.add(b'exp-compression-%s' % name) |