##// END OF EJS Templates
upgrade: don't create store backup if `--no-backup` is passed...
Pulkit Goyal -
r47092:2e8a844d default
parent child Browse files
Show More
@@ -1,351 +1,346 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from .i18n import _
10 from .i18n import _
11 from . import (
11 from . import (
12 error,
12 error,
13 hg,
13 hg,
14 localrepo,
14 localrepo,
15 lock as lockmod,
15 lock as lockmod,
16 pycompat,
16 pycompat,
17 requirements as requirementsmod,
17 requirements as requirementsmod,
18 scmutil,
18 scmutil,
19 )
19 )
20
20
21 from .upgrade_utils import (
21 from .upgrade_utils import (
22 actions as upgrade_actions,
22 actions as upgrade_actions,
23 engine as upgrade_engine,
23 engine as upgrade_engine,
24 )
24 )
25
25
26 from .utils import (
26 from .utils import (
27 stringutil,
27 stringutil,
28 )
28 )
29
29
30 allformatvariant = upgrade_actions.allformatvariant
30 allformatvariant = upgrade_actions.allformatvariant
31
31
32
32
33 def upgraderepo(
33 def upgraderepo(
34 ui,
34 ui,
35 repo,
35 repo,
36 run=False,
36 run=False,
37 optimize=None,
37 optimize=None,
38 backup=True,
38 backup=True,
39 manifest=None,
39 manifest=None,
40 changelog=None,
40 changelog=None,
41 filelogs=None,
41 filelogs=None,
42 ):
42 ):
43 """Upgrade a repository in place."""
43 """Upgrade a repository in place."""
44 if optimize is None:
44 if optimize is None:
45 optimize = {}
45 optimize = {}
46 repo = repo.unfiltered()
46 repo = repo.unfiltered()
47
47
48 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
48 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
49 specentries = (
49 specentries = (
50 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
50 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
51 (upgrade_engine.UPGRADE_MANIFEST, manifest),
51 (upgrade_engine.UPGRADE_MANIFEST, manifest),
52 (upgrade_engine.UPGRADE_FILELOGS, filelogs),
52 (upgrade_engine.UPGRADE_FILELOGS, filelogs),
53 )
53 )
54 specified = [(y, x) for (y, x) in specentries if x is not None]
54 specified = [(y, x) for (y, x) in specentries if x is not None]
55 if specified:
55 if specified:
56 # we have some limitation on revlogs to be recloned
56 # we have some limitation on revlogs to be recloned
57 if any(x for y, x in specified):
57 if any(x for y, x in specified):
58 revlogs = set()
58 revlogs = set()
59 for upgrade, enabled in specified:
59 for upgrade, enabled in specified:
60 if enabled:
60 if enabled:
61 revlogs.add(upgrade)
61 revlogs.add(upgrade)
62 else:
62 else:
63 # none are enabled
63 # none are enabled
64 for upgrade, __ in specified:
64 for upgrade, __ in specified:
65 revlogs.discard(upgrade)
65 revlogs.discard(upgrade)
66
66
67 # Ensure the repository can be upgraded.
67 # Ensure the repository can be upgraded.
68 upgrade_actions.check_source_requirements(repo)
68 upgrade_actions.check_source_requirements(repo)
69
69
70 default_options = localrepo.defaultcreateopts(repo.ui)
70 default_options = localrepo.defaultcreateopts(repo.ui)
71 newreqs = localrepo.newreporequirements(repo.ui, default_options)
71 newreqs = localrepo.newreporequirements(repo.ui, default_options)
72 newreqs.update(upgrade_actions.preservedrequirements(repo))
72 newreqs.update(upgrade_actions.preservedrequirements(repo))
73
73
74 upgrade_actions.check_requirements_changes(repo, newreqs)
74 upgrade_actions.check_requirements_changes(repo, newreqs)
75
75
76 # Find and validate all improvements that can be made.
76 # Find and validate all improvements that can be made.
77 alloptimizations = upgrade_actions.findoptimizations(repo)
77 alloptimizations = upgrade_actions.findoptimizations(repo)
78
78
79 # Apply and Validate arguments.
79 # Apply and Validate arguments.
80 optimizations = []
80 optimizations = []
81 for o in alloptimizations:
81 for o in alloptimizations:
82 if o.name in optimize:
82 if o.name in optimize:
83 optimizations.append(o)
83 optimizations.append(o)
84 optimize.discard(o.name)
84 optimize.discard(o.name)
85
85
86 if optimize: # anything left is unknown
86 if optimize: # anything left is unknown
87 raise error.Abort(
87 raise error.Abort(
88 _(b'unknown optimization action requested: %s')
88 _(b'unknown optimization action requested: %s')
89 % b', '.join(sorted(optimize)),
89 % b', '.join(sorted(optimize)),
90 hint=_(b'run without arguments to see valid optimizations'),
90 hint=_(b'run without arguments to see valid optimizations'),
91 )
91 )
92
92
93 format_upgrades = upgrade_actions.find_format_upgrades(repo)
93 format_upgrades = upgrade_actions.find_format_upgrades(repo)
94 up_actions = upgrade_actions.determine_upgrade_actions(
94 up_actions = upgrade_actions.determine_upgrade_actions(
95 repo, format_upgrades, optimizations, repo.requirements, newreqs
95 repo, format_upgrades, optimizations, repo.requirements, newreqs
96 )
96 )
97 removed_actions = upgrade_actions.find_format_downgrades(repo)
97 removed_actions = upgrade_actions.find_format_downgrades(repo)
98
98
99 removedreqs = repo.requirements - newreqs
99 removedreqs = repo.requirements - newreqs
100 addedreqs = newreqs - repo.requirements
100 addedreqs = newreqs - repo.requirements
101
101
102 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
102 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
103 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
103 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
104 removedreqs | addedreqs
104 removedreqs | addedreqs
105 )
105 )
106 if incompatible:
106 if incompatible:
107 msg = _(
107 msg = _(
108 b'ignoring revlogs selection flags, format requirements '
108 b'ignoring revlogs selection flags, format requirements '
109 b'change: %s\n'
109 b'change: %s\n'
110 )
110 )
111 ui.warn(msg % b', '.join(sorted(incompatible)))
111 ui.warn(msg % b', '.join(sorted(incompatible)))
112 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
112 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
113
113
114 upgrade_op = upgrade_actions.UpgradeOperation(
114 upgrade_op = upgrade_actions.UpgradeOperation(
115 ui,
115 ui,
116 newreqs,
116 newreqs,
117 repo.requirements,
117 repo.requirements,
118 up_actions,
118 up_actions,
119 removed_actions,
119 removed_actions,
120 revlogs,
120 revlogs,
121 backup,
121 )
122 )
122
123
123 if not run:
124 if not run:
124 fromconfig = []
125 fromconfig = []
125 onlydefault = []
126 onlydefault = []
126
127
127 for d in format_upgrades:
128 for d in format_upgrades:
128 if d.fromconfig(repo):
129 if d.fromconfig(repo):
129 fromconfig.append(d)
130 fromconfig.append(d)
130 elif d.default:
131 elif d.default:
131 onlydefault.append(d)
132 onlydefault.append(d)
132
133
133 if fromconfig or onlydefault:
134 if fromconfig or onlydefault:
134
135
135 if fromconfig:
136 if fromconfig:
136 ui.status(
137 ui.status(
137 _(
138 _(
138 b'repository lacks features recommended by '
139 b'repository lacks features recommended by '
139 b'current config options:\n\n'
140 b'current config options:\n\n'
140 )
141 )
141 )
142 )
142 for i in fromconfig:
143 for i in fromconfig:
143 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
144 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
144
145
145 if onlydefault:
146 if onlydefault:
146 ui.status(
147 ui.status(
147 _(
148 _(
148 b'repository lacks features used by the default '
149 b'repository lacks features used by the default '
149 b'config options:\n\n'
150 b'config options:\n\n'
150 )
151 )
151 )
152 )
152 for i in onlydefault:
153 for i in onlydefault:
153 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
154 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
154
155
155 ui.status(b'\n')
156 ui.status(b'\n')
156 else:
157 else:
157 ui.status(_(b'(no format upgrades found in existing repository)\n'))
158 ui.status(_(b'(no format upgrades found in existing repository)\n'))
158
159
159 ui.status(
160 ui.status(
160 _(
161 _(
161 b'performing an upgrade with "--run" will make the following '
162 b'performing an upgrade with "--run" will make the following '
162 b'changes:\n\n'
163 b'changes:\n\n'
163 )
164 )
164 )
165 )
165
166
166 upgrade_op.print_requirements()
167 upgrade_op.print_requirements()
167 upgrade_op.print_optimisations()
168 upgrade_op.print_optimisations()
168 upgrade_op.print_upgrade_actions()
169 upgrade_op.print_upgrade_actions()
169 upgrade_op.print_affected_revlogs()
170 upgrade_op.print_affected_revlogs()
170
171
171 if upgrade_op.unused_optimizations:
172 if upgrade_op.unused_optimizations:
172 ui.status(
173 ui.status(
173 _(
174 _(
174 b'additional optimizations are available by specifying '
175 b'additional optimizations are available by specifying '
175 b'"--optimize <name>":\n\n'
176 b'"--optimize <name>":\n\n'
176 )
177 )
177 )
178 )
178 upgrade_op.print_unused_optimizations()
179 upgrade_op.print_unused_optimizations()
179 return
180 return
180
181
181 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
182 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
182 ui.status(_(b'nothing to do\n'))
183 ui.status(_(b'nothing to do\n'))
183 return
184 return
184 # Else we're in the run=true case.
185 # Else we're in the run=true case.
185 ui.write(_(b'upgrade will perform the following actions:\n\n'))
186 ui.write(_(b'upgrade will perform the following actions:\n\n'))
186 upgrade_op.print_requirements()
187 upgrade_op.print_requirements()
187 upgrade_op.print_optimisations()
188 upgrade_op.print_optimisations()
188 upgrade_op.print_upgrade_actions()
189 upgrade_op.print_upgrade_actions()
189 upgrade_op.print_affected_revlogs()
190 upgrade_op.print_affected_revlogs()
190
191
191 ui.status(_(b'beginning upgrade...\n'))
192 ui.status(_(b'beginning upgrade...\n'))
192 with repo.wlock(), repo.lock():
193 with repo.wlock(), repo.lock():
193 ui.status(_(b'repository locked and read-only\n'))
194 ui.status(_(b'repository locked and read-only\n'))
194 # Our strategy for upgrading the repository is to create a new,
195 # Our strategy for upgrading the repository is to create a new,
195 # temporary repository, write data to it, then do a swap of the
196 # temporary repository, write data to it, then do a swap of the
196 # data. There are less heavyweight ways to do this, but it is easier
197 # data. There are less heavyweight ways to do this, but it is easier
197 # to create a new repo object than to instantiate all the components
198 # to create a new repo object than to instantiate all the components
198 # (like the store) separately.
199 # (like the store) separately.
199 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
200 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
200 backuppath = None
201 backuppath = None
201 try:
202 try:
202 ui.status(
203 ui.status(
203 _(
204 _(
204 b'creating temporary repository to stage upgraded '
205 b'creating temporary repository to stage upgraded '
205 b'data: %s\n'
206 b'data: %s\n'
206 )
207 )
207 % tmppath
208 % tmppath
208 )
209 )
209
210
210 # clone ui without using ui.copy because repo.ui is protected
211 # clone ui without using ui.copy because repo.ui is protected
211 repoui = repo.ui.__class__(repo.ui)
212 repoui = repo.ui.__class__(repo.ui)
212 dstrepo = hg.repository(repoui, path=tmppath, create=True)
213 dstrepo = hg.repository(repoui, path=tmppath, create=True)
213
214
214 with dstrepo.wlock(), dstrepo.lock():
215 with dstrepo.wlock(), dstrepo.lock():
215 backuppath = upgrade_engine.upgrade(
216 backuppath = upgrade_engine.upgrade(
216 ui, repo, dstrepo, upgrade_op
217 ui, repo, dstrepo, upgrade_op
217 )
218 )
218 if not backup:
219 ui.status(
220 _(b'removing old repository content %s\n') % backuppath
221 )
222 repo.vfs.rmtree(backuppath, forcibly=True)
223 backuppath = None
224
219
225 finally:
220 finally:
226 ui.status(_(b'removing temporary repository %s\n') % tmppath)
221 ui.status(_(b'removing temporary repository %s\n') % tmppath)
227 repo.vfs.rmtree(tmppath, forcibly=True)
222 repo.vfs.rmtree(tmppath, forcibly=True)
228
223
229 if backuppath and not ui.quiet:
224 if backuppath and not ui.quiet:
230 ui.warn(
225 ui.warn(
231 _(b'copy of old repository backed up at %s\n') % backuppath
226 _(b'copy of old repository backed up at %s\n') % backuppath
232 )
227 )
233 ui.warn(
228 ui.warn(
234 _(
229 _(
235 b'the old repository will not be deleted; remove '
230 b'the old repository will not be deleted; remove '
236 b'it to free up disk space once the upgraded '
231 b'it to free up disk space once the upgraded '
237 b'repository is verified\n'
232 b'repository is verified\n'
238 )
233 )
239 )
234 )
240
235
241 upgrade_op.print_post_op_messages()
236 upgrade_op.print_post_op_messages()
242
237
243
238
244 def upgrade_share_to_safe(
239 def upgrade_share_to_safe(
245 ui,
240 ui,
246 hgvfs,
241 hgvfs,
247 storevfs,
242 storevfs,
248 current_requirements,
243 current_requirements,
249 mismatch_config,
244 mismatch_config,
250 mismatch_warn,
245 mismatch_warn,
251 ):
246 ):
252 """Upgrades a share to use share-safe mechanism"""
247 """Upgrades a share to use share-safe mechanism"""
253 wlock = None
248 wlock = None
254 store_requirements = localrepo._readrequires(storevfs, False)
249 store_requirements = localrepo._readrequires(storevfs, False)
255 original_crequirements = current_requirements.copy()
250 original_crequirements = current_requirements.copy()
256 # after upgrade, store requires will be shared, so lets find
251 # after upgrade, store requires will be shared, so lets find
257 # the requirements which are not present in store and
252 # the requirements which are not present in store and
258 # write them to share's .hg/requires
253 # write them to share's .hg/requires
259 diffrequires = current_requirements - store_requirements
254 diffrequires = current_requirements - store_requirements
260 # add share-safe requirement as it will mark the share as share-safe
255 # add share-safe requirement as it will mark the share as share-safe
261 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
256 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
262 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
257 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
263 # in `allow` case, we don't try to upgrade, we just respect the source
258 # in `allow` case, we don't try to upgrade, we just respect the source
264 # state, update requirements and continue
259 # state, update requirements and continue
265 if mismatch_config == b'allow':
260 if mismatch_config == b'allow':
266 return
261 return
267 try:
262 try:
268 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
263 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
269 # some process might change the requirement in between, re-read
264 # some process might change the requirement in between, re-read
270 # and update current_requirements
265 # and update current_requirements
271 locked_requirements = localrepo._readrequires(hgvfs, True)
266 locked_requirements = localrepo._readrequires(hgvfs, True)
272 if locked_requirements != original_crequirements:
267 if locked_requirements != original_crequirements:
273 removed = current_requirements - locked_requirements
268 removed = current_requirements - locked_requirements
274 # update current_requirements in place because it's passed
269 # update current_requirements in place because it's passed
275 # as reference
270 # as reference
276 current_requirements -= removed
271 current_requirements -= removed
277 current_requirements |= locked_requirements
272 current_requirements |= locked_requirements
278 diffrequires = current_requirements - store_requirements
273 diffrequires = current_requirements - store_requirements
279 # add share-safe requirement as it will mark the share as share-safe
274 # add share-safe requirement as it will mark the share as share-safe
280 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
275 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
281 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
276 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
282 scmutil.writerequires(hgvfs, diffrequires)
277 scmutil.writerequires(hgvfs, diffrequires)
283 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
278 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
284 except error.LockError as e:
279 except error.LockError as e:
285 if mismatch_config == b'upgrade-abort':
280 if mismatch_config == b'upgrade-abort':
286 raise error.Abort(
281 raise error.Abort(
287 _(b'failed to upgrade share, got error: %s')
282 _(b'failed to upgrade share, got error: %s')
288 % stringutil.forcebytestr(e.strerror)
283 % stringutil.forcebytestr(e.strerror)
289 )
284 )
290 elif mismatch_warn:
285 elif mismatch_warn:
291 ui.warn(
286 ui.warn(
292 _(b'failed to upgrade share, got error: %s\n')
287 _(b'failed to upgrade share, got error: %s\n')
293 % stringutil.forcebytestr(e.strerror)
288 % stringutil.forcebytestr(e.strerror)
294 )
289 )
295 finally:
290 finally:
296 if wlock:
291 if wlock:
297 wlock.release()
292 wlock.release()
298
293
299
294
300 def downgrade_share_to_non_safe(
295 def downgrade_share_to_non_safe(
301 ui,
296 ui,
302 hgvfs,
297 hgvfs,
303 sharedvfs,
298 sharedvfs,
304 current_requirements,
299 current_requirements,
305 mismatch_config,
300 mismatch_config,
306 mismatch_warn,
301 mismatch_warn,
307 ):
302 ):
308 """Downgrades a share which use share-safe to not use it"""
303 """Downgrades a share which use share-safe to not use it"""
309 wlock = None
304 wlock = None
310 source_requirements = localrepo._readrequires(sharedvfs, True)
305 source_requirements = localrepo._readrequires(sharedvfs, True)
311 original_crequirements = current_requirements.copy()
306 original_crequirements = current_requirements.copy()
312 # we cannot be 100% sure on which requirements were present in store when
307 # we cannot be 100% sure on which requirements were present in store when
313 # the source supported share-safe. However, we do know that working
308 # the source supported share-safe. However, we do know that working
314 # directory requirements were not there. Hence we remove them
309 # directory requirements were not there. Hence we remove them
315 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
310 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
316 current_requirements |= source_requirements
311 current_requirements |= source_requirements
317 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
312 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
318 if mismatch_config == b'allow':
313 if mismatch_config == b'allow':
319 return
314 return
320
315
321 try:
316 try:
322 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
317 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
323 # some process might change the requirement in between, re-read
318 # some process might change the requirement in between, re-read
324 # and update current_requirements
319 # and update current_requirements
325 locked_requirements = localrepo._readrequires(hgvfs, True)
320 locked_requirements = localrepo._readrequires(hgvfs, True)
326 if locked_requirements != original_crequirements:
321 if locked_requirements != original_crequirements:
327 removed = current_requirements - locked_requirements
322 removed = current_requirements - locked_requirements
328 # update current_requirements in place because it's passed
323 # update current_requirements in place because it's passed
329 # as reference
324 # as reference
330 current_requirements -= removed
325 current_requirements -= removed
331 current_requirements |= locked_requirements
326 current_requirements |= locked_requirements
332 current_requirements |= source_requirements
327 current_requirements |= source_requirements
333 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
328 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
334 scmutil.writerequires(hgvfs, current_requirements)
329 scmutil.writerequires(hgvfs, current_requirements)
335 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
330 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
336 except error.LockError as e:
331 except error.LockError as e:
337 # If upgrade-abort is set, abort when upgrade fails, else let the
332 # If upgrade-abort is set, abort when upgrade fails, else let the
338 # process continue as `upgrade-allow` is set
333 # process continue as `upgrade-allow` is set
339 if mismatch_config == b'downgrade-abort':
334 if mismatch_config == b'downgrade-abort':
340 raise error.Abort(
335 raise error.Abort(
341 _(b'failed to downgrade share, got error: %s')
336 _(b'failed to downgrade share, got error: %s')
342 % stringutil.forcebytestr(e.strerror)
337 % stringutil.forcebytestr(e.strerror)
343 )
338 )
344 elif mismatch_warn:
339 elif mismatch_warn:
345 ui.warn(
340 ui.warn(
346 _(b'failed to downgrade share, got error: %s\n')
341 _(b'failed to downgrade share, got error: %s\n')
347 % stringutil.forcebytestr(e.strerror)
342 % stringutil.forcebytestr(e.strerror)
348 )
343 )
349 finally:
344 finally:
350 if wlock:
345 if wlock:
351 wlock.release()
346 wlock.release()
@@ -1,911 +1,915 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from ..i18n import _
10 from ..i18n import _
11 from .. import (
11 from .. import (
12 error,
12 error,
13 localrepo,
13 localrepo,
14 requirements,
14 requirements,
15 revlog,
15 revlog,
16 util,
16 util,
17 )
17 )
18
18
19 from ..utils import compression
19 from ..utils import compression
20
20
21 # list of requirements that request a clone of all revlog if added/removed
21 # list of requirements that request a clone of all revlog if added/removed
22 RECLONES_REQUIREMENTS = {
22 RECLONES_REQUIREMENTS = {
23 b'generaldelta',
23 b'generaldelta',
24 requirements.SPARSEREVLOG_REQUIREMENT,
24 requirements.SPARSEREVLOG_REQUIREMENT,
25 }
25 }
26
26
27
27
28 def preservedrequirements(repo):
28 def preservedrequirements(repo):
29 return set()
29 return set()
30
30
31
31
32 FORMAT_VARIANT = b'deficiency'
32 FORMAT_VARIANT = b'deficiency'
33 OPTIMISATION = b'optimization'
33 OPTIMISATION = b'optimization'
34
34
35
35
36 class improvement(object):
36 class improvement(object):
37 """Represents an improvement that can be made as part of an upgrade.
37 """Represents an improvement that can be made as part of an upgrade.
38
38
39 The following attributes are defined on each instance:
39 The following attributes are defined on each instance:
40
40
41 name
41 name
42 Machine-readable string uniquely identifying this improvement. It
42 Machine-readable string uniquely identifying this improvement. It
43 will be mapped to an action later in the upgrade process.
43 will be mapped to an action later in the upgrade process.
44
44
45 type
45 type
46 Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
46 Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
47 A format variant is where we change the storage format. Not all format
47 A format variant is where we change the storage format. Not all format
48 variant changes are an obvious problem.
48 variant changes are an obvious problem.
49 An optimization is an action (sometimes optional) that
49 An optimization is an action (sometimes optional) that
50 can be taken to further improve the state of the repository.
50 can be taken to further improve the state of the repository.
51
51
52 description
52 description
53 Message intended for humans explaining the improvement in more detail,
53 Message intended for humans explaining the improvement in more detail,
54 including the implications of it. For ``FORMAT_VARIANT`` types, should be
54 including the implications of it. For ``FORMAT_VARIANT`` types, should be
55 worded in the present tense. For ``OPTIMISATION`` types, should be
55 worded in the present tense. For ``OPTIMISATION`` types, should be
56 worded in the future tense.
56 worded in the future tense.
57
57
58 upgrademessage
58 upgrademessage
59 Message intended for humans explaining what an upgrade addressing this
59 Message intended for humans explaining what an upgrade addressing this
60 issue will do. Should be worded in the future tense.
60 issue will do. Should be worded in the future tense.
61
61
62 postupgrademessage
62 postupgrademessage
63 Message intended for humans which will be shown post an upgrade
63 Message intended for humans which will be shown post an upgrade
64 operation when the improvement will be added
64 operation when the improvement will be added
65
65
66 postdowngrademessage
66 postdowngrademessage
67 Message intended for humans which will be shown post an upgrade
67 Message intended for humans which will be shown post an upgrade
68 operation in which this improvement was removed
68 operation in which this improvement was removed
69 """
69 """
70
70
71 def __init__(self, name, type, description, upgrademessage):
71 def __init__(self, name, type, description, upgrademessage):
72 self.name = name
72 self.name = name
73 self.type = type
73 self.type = type
74 self.description = description
74 self.description = description
75 self.upgrademessage = upgrademessage
75 self.upgrademessage = upgrademessage
76 self.postupgrademessage = None
76 self.postupgrademessage = None
77 self.postdowngrademessage = None
77 self.postdowngrademessage = None
78
78
79 def __eq__(self, other):
79 def __eq__(self, other):
80 if not isinstance(other, improvement):
80 if not isinstance(other, improvement):
81 # This is what python tell use to do
81 # This is what python tell use to do
82 return NotImplemented
82 return NotImplemented
83 return self.name == other.name
83 return self.name == other.name
84
84
85 def __ne__(self, other):
85 def __ne__(self, other):
86 return not (self == other)
86 return not (self == other)
87
87
88 def __hash__(self):
88 def __hash__(self):
89 return hash(self.name)
89 return hash(self.name)
90
90
91
91
92 allformatvariant = []
92 allformatvariant = []
93
93
94
94
95 def registerformatvariant(cls):
95 def registerformatvariant(cls):
96 allformatvariant.append(cls)
96 allformatvariant.append(cls)
97 return cls
97 return cls
98
98
99
99
100 class formatvariant(improvement):
100 class formatvariant(improvement):
101 """an improvement subclass dedicated to repository format"""
101 """an improvement subclass dedicated to repository format"""
102
102
103 type = FORMAT_VARIANT
103 type = FORMAT_VARIANT
104 ### The following attributes should be defined for each class:
104 ### The following attributes should be defined for each class:
105
105
106 # machine-readable string uniquely identifying this improvement. it will be
106 # machine-readable string uniquely identifying this improvement. it will be
107 # mapped to an action later in the upgrade process.
107 # mapped to an action later in the upgrade process.
108 name = None
108 name = None
109
109
110 # message intended for humans explaining the improvement in more detail,
110 # message intended for humans explaining the improvement in more detail,
111 # including the implications of it ``FORMAT_VARIANT`` types, should be
111 # including the implications of it ``FORMAT_VARIANT`` types, should be
112 # worded
112 # worded
113 # in the present tense.
113 # in the present tense.
114 description = None
114 description = None
115
115
116 # message intended for humans explaining what an upgrade addressing this
116 # message intended for humans explaining what an upgrade addressing this
117 # issue will do. should be worded in the future tense.
117 # issue will do. should be worded in the future tense.
118 upgrademessage = None
118 upgrademessage = None
119
119
120 # value of current Mercurial default for new repository
120 # value of current Mercurial default for new repository
121 default = None
121 default = None
122
122
123 # Message intended for humans which will be shown post an upgrade
123 # Message intended for humans which will be shown post an upgrade
124 # operation when the improvement will be added
124 # operation when the improvement will be added
125 postupgrademessage = None
125 postupgrademessage = None
126
126
127 # Message intended for humans which will be shown post an upgrade
127 # Message intended for humans which will be shown post an upgrade
128 # operation in which this improvement was removed
128 # operation in which this improvement was removed
129 postdowngrademessage = None
129 postdowngrademessage = None
130
130
131 def __init__(self):
131 def __init__(self):
132 raise NotImplementedError()
132 raise NotImplementedError()
133
133
134 @staticmethod
134 @staticmethod
135 def fromrepo(repo):
135 def fromrepo(repo):
136 """current value of the variant in the repository"""
136 """current value of the variant in the repository"""
137 raise NotImplementedError()
137 raise NotImplementedError()
138
138
139 @staticmethod
139 @staticmethod
140 def fromconfig(repo):
140 def fromconfig(repo):
141 """current value of the variant in the configuration"""
141 """current value of the variant in the configuration"""
142 raise NotImplementedError()
142 raise NotImplementedError()
143
143
144
144
145 class requirementformatvariant(formatvariant):
145 class requirementformatvariant(formatvariant):
146 """formatvariant based on a 'requirement' name.
146 """formatvariant based on a 'requirement' name.
147
147
148 Many format variant are controlled by a 'requirement'. We define a small
148 Many format variant are controlled by a 'requirement'. We define a small
149 subclass to factor the code.
149 subclass to factor the code.
150 """
150 """
151
151
152 # the requirement that control this format variant
152 # the requirement that control this format variant
153 _requirement = None
153 _requirement = None
154
154
155 @staticmethod
155 @staticmethod
156 def _newreporequirements(ui):
156 def _newreporequirements(ui):
157 return localrepo.newreporequirements(
157 return localrepo.newreporequirements(
158 ui, localrepo.defaultcreateopts(ui)
158 ui, localrepo.defaultcreateopts(ui)
159 )
159 )
160
160
161 @classmethod
161 @classmethod
162 def fromrepo(cls, repo):
162 def fromrepo(cls, repo):
163 assert cls._requirement is not None
163 assert cls._requirement is not None
164 return cls._requirement in repo.requirements
164 return cls._requirement in repo.requirements
165
165
166 @classmethod
166 @classmethod
167 def fromconfig(cls, repo):
167 def fromconfig(cls, repo):
168 assert cls._requirement is not None
168 assert cls._requirement is not None
169 return cls._requirement in cls._newreporequirements(repo.ui)
169 return cls._requirement in cls._newreporequirements(repo.ui)
170
170
171
171
172 @registerformatvariant
172 @registerformatvariant
173 class fncache(requirementformatvariant):
173 class fncache(requirementformatvariant):
174 name = b'fncache'
174 name = b'fncache'
175
175
176 _requirement = b'fncache'
176 _requirement = b'fncache'
177
177
178 default = True
178 default = True
179
179
180 description = _(
180 description = _(
181 b'long and reserved filenames may not work correctly; '
181 b'long and reserved filenames may not work correctly; '
182 b'repository performance is sub-optimal'
182 b'repository performance is sub-optimal'
183 )
183 )
184
184
185 upgrademessage = _(
185 upgrademessage = _(
186 b'repository will be more resilient to storing '
186 b'repository will be more resilient to storing '
187 b'certain paths and performance of certain '
187 b'certain paths and performance of certain '
188 b'operations should be improved'
188 b'operations should be improved'
189 )
189 )
190
190
191
191
192 @registerformatvariant
192 @registerformatvariant
193 class dotencode(requirementformatvariant):
193 class dotencode(requirementformatvariant):
194 name = b'dotencode'
194 name = b'dotencode'
195
195
196 _requirement = b'dotencode'
196 _requirement = b'dotencode'
197
197
198 default = True
198 default = True
199
199
200 description = _(
200 description = _(
201 b'storage of filenames beginning with a period or '
201 b'storage of filenames beginning with a period or '
202 b'space may not work correctly'
202 b'space may not work correctly'
203 )
203 )
204
204
205 upgrademessage = _(
205 upgrademessage = _(
206 b'repository will be better able to store files '
206 b'repository will be better able to store files '
207 b'beginning with a space or period'
207 b'beginning with a space or period'
208 )
208 )
209
209
210
210
211 @registerformatvariant
211 @registerformatvariant
212 class generaldelta(requirementformatvariant):
212 class generaldelta(requirementformatvariant):
213 name = b'generaldelta'
213 name = b'generaldelta'
214
214
215 _requirement = b'generaldelta'
215 _requirement = b'generaldelta'
216
216
217 default = True
217 default = True
218
218
219 description = _(
219 description = _(
220 b'deltas within internal storage are unable to '
220 b'deltas within internal storage are unable to '
221 b'choose optimal revisions; repository is larger and '
221 b'choose optimal revisions; repository is larger and '
222 b'slower than it could be; interaction with other '
222 b'slower than it could be; interaction with other '
223 b'repositories may require extra network and CPU '
223 b'repositories may require extra network and CPU '
224 b'resources, making "hg push" and "hg pull" slower'
224 b'resources, making "hg push" and "hg pull" slower'
225 )
225 )
226
226
227 upgrademessage = _(
227 upgrademessage = _(
228 b'repository storage will be able to create '
228 b'repository storage will be able to create '
229 b'optimal deltas; new repository data will be '
229 b'optimal deltas; new repository data will be '
230 b'smaller and read times should decrease; '
230 b'smaller and read times should decrease; '
231 b'interacting with other repositories using this '
231 b'interacting with other repositories using this '
232 b'storage model should require less network and '
232 b'storage model should require less network and '
233 b'CPU resources, making "hg push" and "hg pull" '
233 b'CPU resources, making "hg push" and "hg pull" '
234 b'faster'
234 b'faster'
235 )
235 )
236
236
237
237
238 @registerformatvariant
238 @registerformatvariant
239 class sharesafe(requirementformatvariant):
239 class sharesafe(requirementformatvariant):
240 name = b'share-safe'
240 name = b'share-safe'
241 _requirement = requirements.SHARESAFE_REQUIREMENT
241 _requirement = requirements.SHARESAFE_REQUIREMENT
242
242
243 default = False
243 default = False
244
244
245 description = _(
245 description = _(
246 b'old shared repositories do not share source repository '
246 b'old shared repositories do not share source repository '
247 b'requirements and config. This leads to various problems '
247 b'requirements and config. This leads to various problems '
248 b'when the source repository format is upgraded or some new '
248 b'when the source repository format is upgraded or some new '
249 b'extensions are enabled.'
249 b'extensions are enabled.'
250 )
250 )
251
251
252 upgrademessage = _(
252 upgrademessage = _(
253 b'Upgrades a repository to share-safe format so that future '
253 b'Upgrades a repository to share-safe format so that future '
254 b'shares of this repository share its requirements and configs.'
254 b'shares of this repository share its requirements and configs.'
255 )
255 )
256
256
257 postdowngrademessage = _(
257 postdowngrademessage = _(
258 b'repository downgraded to not use share safe mode, '
258 b'repository downgraded to not use share safe mode, '
259 b'existing shares will not work and needs to'
259 b'existing shares will not work and needs to'
260 b' be reshared.'
260 b' be reshared.'
261 )
261 )
262
262
263 postupgrademessage = _(
263 postupgrademessage = _(
264 b'repository upgraded to share safe mode, existing'
264 b'repository upgraded to share safe mode, existing'
265 b' shares will still work in old non-safe mode. '
265 b' shares will still work in old non-safe mode. '
266 b'Re-share existing shares to use them in safe mode'
266 b'Re-share existing shares to use them in safe mode'
267 b' New shares will be created in safe mode.'
267 b' New shares will be created in safe mode.'
268 )
268 )
269
269
270
270
271 @registerformatvariant
271 @registerformatvariant
272 class sparserevlog(requirementformatvariant):
272 class sparserevlog(requirementformatvariant):
273 name = b'sparserevlog'
273 name = b'sparserevlog'
274
274
275 _requirement = requirements.SPARSEREVLOG_REQUIREMENT
275 _requirement = requirements.SPARSEREVLOG_REQUIREMENT
276
276
277 default = True
277 default = True
278
278
279 description = _(
279 description = _(
280 b'in order to limit disk reading and memory usage on older '
280 b'in order to limit disk reading and memory usage on older '
281 b'version, the span of a delta chain from its root to its '
281 b'version, the span of a delta chain from its root to its '
282 b'end is limited, whatever the relevant data in this span. '
282 b'end is limited, whatever the relevant data in this span. '
283 b'This can severly limit Mercurial ability to build good '
283 b'This can severly limit Mercurial ability to build good '
284 b'chain of delta resulting is much more storage space being '
284 b'chain of delta resulting is much more storage space being '
285 b'taken and limit reusability of on disk delta during '
285 b'taken and limit reusability of on disk delta during '
286 b'exchange.'
286 b'exchange.'
287 )
287 )
288
288
289 upgrademessage = _(
289 upgrademessage = _(
290 b'Revlog supports delta chain with more unused data '
290 b'Revlog supports delta chain with more unused data '
291 b'between payload. These gaps will be skipped at read '
291 b'between payload. These gaps will be skipped at read '
292 b'time. This allows for better delta chains, making a '
292 b'time. This allows for better delta chains, making a '
293 b'better compression and faster exchange with server.'
293 b'better compression and faster exchange with server.'
294 )
294 )
295
295
296
296
297 @registerformatvariant
297 @registerformatvariant
298 class sidedata(requirementformatvariant):
298 class sidedata(requirementformatvariant):
299 name = b'sidedata'
299 name = b'sidedata'
300
300
301 _requirement = requirements.SIDEDATA_REQUIREMENT
301 _requirement = requirements.SIDEDATA_REQUIREMENT
302
302
303 default = False
303 default = False
304
304
305 description = _(
305 description = _(
306 b'Allows storage of extra data alongside a revision, '
306 b'Allows storage of extra data alongside a revision, '
307 b'unlocking various caching options.'
307 b'unlocking various caching options.'
308 )
308 )
309
309
310 upgrademessage = _(b'Allows storage of extra data alongside a revision.')
310 upgrademessage = _(b'Allows storage of extra data alongside a revision.')
311
311
312
312
313 @registerformatvariant
313 @registerformatvariant
314 class persistentnodemap(requirementformatvariant):
314 class persistentnodemap(requirementformatvariant):
315 name = b'persistent-nodemap'
315 name = b'persistent-nodemap'
316
316
317 _requirement = requirements.NODEMAP_REQUIREMENT
317 _requirement = requirements.NODEMAP_REQUIREMENT
318
318
319 default = False
319 default = False
320
320
321 description = _(
321 description = _(
322 b'persist the node -> rev mapping on disk to speedup lookup'
322 b'persist the node -> rev mapping on disk to speedup lookup'
323 )
323 )
324
324
325 upgrademessage = _(b'Speedup revision lookup by node id.')
325 upgrademessage = _(b'Speedup revision lookup by node id.')
326
326
327
327
328 @registerformatvariant
328 @registerformatvariant
329 class copiessdc(requirementformatvariant):
329 class copiessdc(requirementformatvariant):
330 name = b'copies-sdc'
330 name = b'copies-sdc'
331
331
332 _requirement = requirements.COPIESSDC_REQUIREMENT
332 _requirement = requirements.COPIESSDC_REQUIREMENT
333
333
334 default = False
334 default = False
335
335
336 description = _(b'Stores copies information alongside changesets.')
336 description = _(b'Stores copies information alongside changesets.')
337
337
338 upgrademessage = _(
338 upgrademessage = _(
339 b'Allows to use more efficient algorithm to deal with ' b'copy tracing.'
339 b'Allows to use more efficient algorithm to deal with ' b'copy tracing.'
340 )
340 )
341
341
342
342
343 @registerformatvariant
343 @registerformatvariant
344 class removecldeltachain(formatvariant):
344 class removecldeltachain(formatvariant):
345 name = b'plain-cl-delta'
345 name = b'plain-cl-delta'
346
346
347 default = True
347 default = True
348
348
349 description = _(
349 description = _(
350 b'changelog storage is using deltas instead of '
350 b'changelog storage is using deltas instead of '
351 b'raw entries; changelog reading and any '
351 b'raw entries; changelog reading and any '
352 b'operation relying on changelog data are slower '
352 b'operation relying on changelog data are slower '
353 b'than they could be'
353 b'than they could be'
354 )
354 )
355
355
356 upgrademessage = _(
356 upgrademessage = _(
357 b'changelog storage will be reformated to '
357 b'changelog storage will be reformated to '
358 b'store raw entries; changelog reading will be '
358 b'store raw entries; changelog reading will be '
359 b'faster; changelog size may be reduced'
359 b'faster; changelog size may be reduced'
360 )
360 )
361
361
362 @staticmethod
362 @staticmethod
363 def fromrepo(repo):
363 def fromrepo(repo):
364 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
364 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
365 # changelogs with deltas.
365 # changelogs with deltas.
366 cl = repo.changelog
366 cl = repo.changelog
367 chainbase = cl.chainbase
367 chainbase = cl.chainbase
368 return all(rev == chainbase(rev) for rev in cl)
368 return all(rev == chainbase(rev) for rev in cl)
369
369
370 @staticmethod
370 @staticmethod
371 def fromconfig(repo):
371 def fromconfig(repo):
372 return True
372 return True
373
373
374
374
375 @registerformatvariant
375 @registerformatvariant
376 class compressionengine(formatvariant):
376 class compressionengine(formatvariant):
377 name = b'compression'
377 name = b'compression'
378 default = b'zlib'
378 default = b'zlib'
379
379
380 description = _(
380 description = _(
381 b'Compresion algorithm used to compress data. '
381 b'Compresion algorithm used to compress data. '
382 b'Some engine are faster than other'
382 b'Some engine are faster than other'
383 )
383 )
384
384
385 upgrademessage = _(
385 upgrademessage = _(
386 b'revlog content will be recompressed with the new algorithm.'
386 b'revlog content will be recompressed with the new algorithm.'
387 )
387 )
388
388
389 @classmethod
389 @classmethod
390 def fromrepo(cls, repo):
390 def fromrepo(cls, repo):
391 # we allow multiple compression engine requirement to co-exist because
391 # we allow multiple compression engine requirement to co-exist because
392 # strickly speaking, revlog seems to support mixed compression style.
392 # strickly speaking, revlog seems to support mixed compression style.
393 #
393 #
394 # The compression used for new entries will be "the last one"
394 # The compression used for new entries will be "the last one"
395 compression = b'zlib'
395 compression = b'zlib'
396 for req in repo.requirements:
396 for req in repo.requirements:
397 prefix = req.startswith
397 prefix = req.startswith
398 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
398 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
399 compression = req.split(b'-', 2)[2]
399 compression = req.split(b'-', 2)[2]
400 return compression
400 return compression
401
401
402 @classmethod
402 @classmethod
403 def fromconfig(cls, repo):
403 def fromconfig(cls, repo):
404 compengines = repo.ui.configlist(b'format', b'revlog-compression')
404 compengines = repo.ui.configlist(b'format', b'revlog-compression')
405 # return the first valid value as the selection code would do
405 # return the first valid value as the selection code would do
406 for comp in compengines:
406 for comp in compengines:
407 if comp in util.compengines:
407 if comp in util.compengines:
408 return comp
408 return comp
409
409
410 # no valide compression found lets display it all for clarity
410 # no valide compression found lets display it all for clarity
411 return b','.join(compengines)
411 return b','.join(compengines)
412
412
413
413
414 @registerformatvariant
414 @registerformatvariant
415 class compressionlevel(formatvariant):
415 class compressionlevel(formatvariant):
416 name = b'compression-level'
416 name = b'compression-level'
417 default = b'default'
417 default = b'default'
418
418
419 description = _(b'compression level')
419 description = _(b'compression level')
420
420
421 upgrademessage = _(b'revlog content will be recompressed')
421 upgrademessage = _(b'revlog content will be recompressed')
422
422
423 @classmethod
423 @classmethod
424 def fromrepo(cls, repo):
424 def fromrepo(cls, repo):
425 comp = compressionengine.fromrepo(repo)
425 comp = compressionengine.fromrepo(repo)
426 level = None
426 level = None
427 if comp == b'zlib':
427 if comp == b'zlib':
428 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
428 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
429 elif comp == b'zstd':
429 elif comp == b'zstd':
430 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
430 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
431 if level is None:
431 if level is None:
432 return b'default'
432 return b'default'
433 return bytes(level)
433 return bytes(level)
434
434
435 @classmethod
435 @classmethod
436 def fromconfig(cls, repo):
436 def fromconfig(cls, repo):
437 comp = compressionengine.fromconfig(repo)
437 comp = compressionengine.fromconfig(repo)
438 level = None
438 level = None
439 if comp == b'zlib':
439 if comp == b'zlib':
440 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
440 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
441 elif comp == b'zstd':
441 elif comp == b'zstd':
442 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
442 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
443 if level is None:
443 if level is None:
444 return b'default'
444 return b'default'
445 return bytes(level)
445 return bytes(level)
446
446
447
447
448 def find_format_upgrades(repo):
448 def find_format_upgrades(repo):
449 """returns a list of format upgrades which can be perform on the repo"""
449 """returns a list of format upgrades which can be perform on the repo"""
450 upgrades = []
450 upgrades = []
451
451
452 # We could detect lack of revlogv1 and store here, but they were added
452 # We could detect lack of revlogv1 and store here, but they were added
453 # in 0.9.2 and we don't support upgrading repos without these
453 # in 0.9.2 and we don't support upgrading repos without these
454 # requirements, so let's not bother.
454 # requirements, so let's not bother.
455
455
456 for fv in allformatvariant:
456 for fv in allformatvariant:
457 if not fv.fromrepo(repo):
457 if not fv.fromrepo(repo):
458 upgrades.append(fv)
458 upgrades.append(fv)
459
459
460 return upgrades
460 return upgrades
461
461
462
462
463 def find_format_downgrades(repo):
463 def find_format_downgrades(repo):
464 """returns a list of format downgrades which will be performed on the repo
464 """returns a list of format downgrades which will be performed on the repo
465 because of disabled config option for them"""
465 because of disabled config option for them"""
466
466
467 downgrades = []
467 downgrades = []
468
468
469 for fv in allformatvariant:
469 for fv in allformatvariant:
470 if fv.name == b'compression':
470 if fv.name == b'compression':
471 # If there is a compression change between repository
471 # If there is a compression change between repository
472 # and config, destination repository compression will change
472 # and config, destination repository compression will change
473 # and current compression will be removed.
473 # and current compression will be removed.
474 if fv.fromrepo(repo) != fv.fromconfig(repo):
474 if fv.fromrepo(repo) != fv.fromconfig(repo):
475 downgrades.append(fv)
475 downgrades.append(fv)
476 continue
476 continue
477 # format variant exist in repo but does not exist in new repository
477 # format variant exist in repo but does not exist in new repository
478 # config
478 # config
479 if fv.fromrepo(repo) and not fv.fromconfig(repo):
479 if fv.fromrepo(repo) and not fv.fromconfig(repo):
480 downgrades.append(fv)
480 downgrades.append(fv)
481
481
482 return downgrades
482 return downgrades
483
483
484
484
485 ALL_OPTIMISATIONS = []
485 ALL_OPTIMISATIONS = []
486
486
487
487
488 def register_optimization(obj):
488 def register_optimization(obj):
489 ALL_OPTIMISATIONS.append(obj)
489 ALL_OPTIMISATIONS.append(obj)
490 return obj
490 return obj
491
491
492
492
493 register_optimization(
493 register_optimization(
494 improvement(
494 improvement(
495 name=b're-delta-parent',
495 name=b're-delta-parent',
496 type=OPTIMISATION,
496 type=OPTIMISATION,
497 description=_(
497 description=_(
498 b'deltas within internal storage will be recalculated to '
498 b'deltas within internal storage will be recalculated to '
499 b'choose an optimal base revision where this was not '
499 b'choose an optimal base revision where this was not '
500 b'already done; the size of the repository may shrink and '
500 b'already done; the size of the repository may shrink and '
501 b'various operations may become faster; the first time '
501 b'various operations may become faster; the first time '
502 b'this optimization is performed could slow down upgrade '
502 b'this optimization is performed could slow down upgrade '
503 b'execution considerably; subsequent invocations should '
503 b'execution considerably; subsequent invocations should '
504 b'not run noticeably slower'
504 b'not run noticeably slower'
505 ),
505 ),
506 upgrademessage=_(
506 upgrademessage=_(
507 b'deltas within internal storage will choose a new '
507 b'deltas within internal storage will choose a new '
508 b'base revision if needed'
508 b'base revision if needed'
509 ),
509 ),
510 )
510 )
511 )
511 )
512
512
513 register_optimization(
513 register_optimization(
514 improvement(
514 improvement(
515 name=b're-delta-multibase',
515 name=b're-delta-multibase',
516 type=OPTIMISATION,
516 type=OPTIMISATION,
517 description=_(
517 description=_(
518 b'deltas within internal storage will be recalculated '
518 b'deltas within internal storage will be recalculated '
519 b'against multiple base revision and the smallest '
519 b'against multiple base revision and the smallest '
520 b'difference will be used; the size of the repository may '
520 b'difference will be used; the size of the repository may '
521 b'shrink significantly when there are many merges; this '
521 b'shrink significantly when there are many merges; this '
522 b'optimization will slow down execution in proportion to '
522 b'optimization will slow down execution in proportion to '
523 b'the number of merges in the repository and the amount '
523 b'the number of merges in the repository and the amount '
524 b'of files in the repository; this slow down should not '
524 b'of files in the repository; this slow down should not '
525 b'be significant unless there are tens of thousands of '
525 b'be significant unless there are tens of thousands of '
526 b'files and thousands of merges'
526 b'files and thousands of merges'
527 ),
527 ),
528 upgrademessage=_(
528 upgrademessage=_(
529 b'deltas within internal storage will choose an '
529 b'deltas within internal storage will choose an '
530 b'optimal delta by computing deltas against multiple '
530 b'optimal delta by computing deltas against multiple '
531 b'parents; may slow down execution time '
531 b'parents; may slow down execution time '
532 b'significantly'
532 b'significantly'
533 ),
533 ),
534 )
534 )
535 )
535 )
536
536
537 register_optimization(
537 register_optimization(
538 improvement(
538 improvement(
539 name=b're-delta-all',
539 name=b're-delta-all',
540 type=OPTIMISATION,
540 type=OPTIMISATION,
541 description=_(
541 description=_(
542 b'deltas within internal storage will always be '
542 b'deltas within internal storage will always be '
543 b'recalculated without reusing prior deltas; this will '
543 b'recalculated without reusing prior deltas; this will '
544 b'likely make execution run several times slower; this '
544 b'likely make execution run several times slower; this '
545 b'optimization is typically not needed'
545 b'optimization is typically not needed'
546 ),
546 ),
547 upgrademessage=_(
547 upgrademessage=_(
548 b'deltas within internal storage will be fully '
548 b'deltas within internal storage will be fully '
549 b'recomputed; this will likely drastically slow down '
549 b'recomputed; this will likely drastically slow down '
550 b'execution time'
550 b'execution time'
551 ),
551 ),
552 )
552 )
553 )
553 )
554
554
555 register_optimization(
555 register_optimization(
556 improvement(
556 improvement(
557 name=b're-delta-fulladd',
557 name=b're-delta-fulladd',
558 type=OPTIMISATION,
558 type=OPTIMISATION,
559 description=_(
559 description=_(
560 b'every revision will be re-added as if it was new '
560 b'every revision will be re-added as if it was new '
561 b'content. It will go through the full storage '
561 b'content. It will go through the full storage '
562 b'mechanism giving extensions a chance to process it '
562 b'mechanism giving extensions a chance to process it '
563 b'(eg. lfs). This is similar to "re-delta-all" but even '
563 b'(eg. lfs). This is similar to "re-delta-all" but even '
564 b'slower since more logic is involved.'
564 b'slower since more logic is involved.'
565 ),
565 ),
566 upgrademessage=_(
566 upgrademessage=_(
567 b'each revision will be added as new content to the '
567 b'each revision will be added as new content to the '
568 b'internal storage; this will likely drastically slow '
568 b'internal storage; this will likely drastically slow '
569 b'down execution time, but some extensions might need '
569 b'down execution time, but some extensions might need '
570 b'it'
570 b'it'
571 ),
571 ),
572 )
572 )
573 )
573 )
574
574
575
575
576 def findoptimizations(repo):
576 def findoptimizations(repo):
577 """Determine optimisation that could be used during upgrade"""
577 """Determine optimisation that could be used during upgrade"""
578 # These are unconditionally added. There is logic later that figures out
578 # These are unconditionally added. There is logic later that figures out
579 # which ones to apply.
579 # which ones to apply.
580 return list(ALL_OPTIMISATIONS)
580 return list(ALL_OPTIMISATIONS)
581
581
582
582
583 def determine_upgrade_actions(
583 def determine_upgrade_actions(
584 repo, format_upgrades, optimizations, sourcereqs, destreqs
584 repo, format_upgrades, optimizations, sourcereqs, destreqs
585 ):
585 ):
586 """Determine upgrade actions that will be performed.
586 """Determine upgrade actions that will be performed.
587
587
588 Given a list of improvements as returned by ``find_format_upgrades`` and
588 Given a list of improvements as returned by ``find_format_upgrades`` and
589 ``findoptimizations``, determine the list of upgrade actions that
589 ``findoptimizations``, determine the list of upgrade actions that
590 will be performed.
590 will be performed.
591
591
592 The role of this function is to filter improvements if needed, apply
592 The role of this function is to filter improvements if needed, apply
593 recommended optimizations from the improvements list that make sense,
593 recommended optimizations from the improvements list that make sense,
594 etc.
594 etc.
595
595
596 Returns a list of action names.
596 Returns a list of action names.
597 """
597 """
598 newactions = []
598 newactions = []
599
599
600 for d in format_upgrades:
600 for d in format_upgrades:
601 name = d._requirement
601 name = d._requirement
602
602
603 # If the action is a requirement that doesn't show up in the
603 # If the action is a requirement that doesn't show up in the
604 # destination requirements, prune the action.
604 # destination requirements, prune the action.
605 if name is not None and name not in destreqs:
605 if name is not None and name not in destreqs:
606 continue
606 continue
607
607
608 newactions.append(d)
608 newactions.append(d)
609
609
610 newactions.extend(o for o in sorted(optimizations) if o not in newactions)
610 newactions.extend(o for o in sorted(optimizations) if o not in newactions)
611
611
612 # FUTURE consider adding some optimizations here for certain transitions.
612 # FUTURE consider adding some optimizations here for certain transitions.
613 # e.g. adding generaldelta could schedule parent redeltas.
613 # e.g. adding generaldelta could schedule parent redeltas.
614
614
615 return newactions
615 return newactions
616
616
617
617
618 class UpgradeOperation(object):
618 class UpgradeOperation(object):
619 """represent the work to be done during an upgrade"""
619 """represent the work to be done during an upgrade"""
620
620
621 def __init__(
621 def __init__(
622 self,
622 self,
623 ui,
623 ui,
624 new_requirements,
624 new_requirements,
625 current_requirements,
625 current_requirements,
626 upgrade_actions,
626 upgrade_actions,
627 removed_actions,
627 removed_actions,
628 revlogs_to_process,
628 revlogs_to_process,
629 backup_store,
629 ):
630 ):
630 self.ui = ui
631 self.ui = ui
631 self.new_requirements = new_requirements
632 self.new_requirements = new_requirements
632 self.current_requirements = current_requirements
633 self.current_requirements = current_requirements
633 # list of upgrade actions the operation will perform
634 # list of upgrade actions the operation will perform
634 self.upgrade_actions = upgrade_actions
635 self.upgrade_actions = upgrade_actions
635 self._upgrade_actions_names = set([a.name for a in upgrade_actions])
636 self._upgrade_actions_names = set([a.name for a in upgrade_actions])
636 self.removed_actions = removed_actions
637 self.removed_actions = removed_actions
637 self.revlogs_to_process = revlogs_to_process
638 self.revlogs_to_process = revlogs_to_process
638 # requirements which will be added by the operation
639 # requirements which will be added by the operation
639 self._added_requirements = (
640 self._added_requirements = (
640 self.new_requirements - self.current_requirements
641 self.new_requirements - self.current_requirements
641 )
642 )
642 # requirements which will be removed by the operation
643 # requirements which will be removed by the operation
643 self._removed_requirements = (
644 self._removed_requirements = (
644 self.current_requirements - self.new_requirements
645 self.current_requirements - self.new_requirements
645 )
646 )
646 # requirements which will be preserved by the operation
647 # requirements which will be preserved by the operation
647 self._preserved_requirements = (
648 self._preserved_requirements = (
648 self.current_requirements & self.new_requirements
649 self.current_requirements & self.new_requirements
649 )
650 )
650 # optimizations which are not used and it's recommended that they
651 # optimizations which are not used and it's recommended that they
651 # should use them
652 # should use them
652 all_optimizations = findoptimizations(None)
653 all_optimizations = findoptimizations(None)
653 self.unused_optimizations = [
654 self.unused_optimizations = [
654 i for i in all_optimizations if i not in self.upgrade_actions
655 i for i in all_optimizations if i not in self.upgrade_actions
655 ]
656 ]
656
657
657 # delta reuse mode of this upgrade operation
658 # delta reuse mode of this upgrade operation
658 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS
659 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS
659 if b're-delta-all' in self._upgrade_actions_names:
660 if b're-delta-all' in self._upgrade_actions_names:
660 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER
661 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER
661 elif b're-delta-parent' in self._upgrade_actions_names:
662 elif b're-delta-parent' in self._upgrade_actions_names:
662 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
663 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
663 elif b're-delta-multibase' in self._upgrade_actions_names:
664 elif b're-delta-multibase' in self._upgrade_actions_names:
664 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
665 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
665 elif b're-delta-fulladd' in self._upgrade_actions_names:
666 elif b're-delta-fulladd' in self._upgrade_actions_names:
666 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD
667 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD
667
668
668 # should this operation force re-delta of both parents
669 # should this operation force re-delta of both parents
669 self.force_re_delta_both_parents = (
670 self.force_re_delta_both_parents = (
670 b're-delta-multibase' in self._upgrade_actions_names
671 b're-delta-multibase' in self._upgrade_actions_names
671 )
672 )
672
673
674 # should this operation create a backup of the store
675 self.backup_store = backup_store
676
673 def _write_labeled(self, l, label):
677 def _write_labeled(self, l, label):
674 """
678 """
675 Utility function to aid writing of a list under one label
679 Utility function to aid writing of a list under one label
676 """
680 """
677 first = True
681 first = True
678 for r in sorted(l):
682 for r in sorted(l):
679 if not first:
683 if not first:
680 self.ui.write(b', ')
684 self.ui.write(b', ')
681 self.ui.write(r, label=label)
685 self.ui.write(r, label=label)
682 first = False
686 first = False
683
687
684 def print_requirements(self):
688 def print_requirements(self):
685 self.ui.write(_(b'requirements\n'))
689 self.ui.write(_(b'requirements\n'))
686 self.ui.write(_(b' preserved: '))
690 self.ui.write(_(b' preserved: '))
687 self._write_labeled(
691 self._write_labeled(
688 self._preserved_requirements, "upgrade-repo.requirement.preserved"
692 self._preserved_requirements, "upgrade-repo.requirement.preserved"
689 )
693 )
690 self.ui.write((b'\n'))
694 self.ui.write((b'\n'))
691 if self._removed_requirements:
695 if self._removed_requirements:
692 self.ui.write(_(b' removed: '))
696 self.ui.write(_(b' removed: '))
693 self._write_labeled(
697 self._write_labeled(
694 self._removed_requirements, "upgrade-repo.requirement.removed"
698 self._removed_requirements, "upgrade-repo.requirement.removed"
695 )
699 )
696 self.ui.write((b'\n'))
700 self.ui.write((b'\n'))
697 if self._added_requirements:
701 if self._added_requirements:
698 self.ui.write(_(b' added: '))
702 self.ui.write(_(b' added: '))
699 self._write_labeled(
703 self._write_labeled(
700 self._added_requirements, "upgrade-repo.requirement.added"
704 self._added_requirements, "upgrade-repo.requirement.added"
701 )
705 )
702 self.ui.write((b'\n'))
706 self.ui.write((b'\n'))
703 self.ui.write(b'\n')
707 self.ui.write(b'\n')
704
708
705 def print_optimisations(self):
709 def print_optimisations(self):
706 optimisations = [
710 optimisations = [
707 a for a in self.upgrade_actions if a.type == OPTIMISATION
711 a for a in self.upgrade_actions if a.type == OPTIMISATION
708 ]
712 ]
709 optimisations.sort(key=lambda a: a.name)
713 optimisations.sort(key=lambda a: a.name)
710 if optimisations:
714 if optimisations:
711 self.ui.write(_(b'optimisations: '))
715 self.ui.write(_(b'optimisations: '))
712 self._write_labeled(
716 self._write_labeled(
713 [a.name for a in optimisations],
717 [a.name for a in optimisations],
714 "upgrade-repo.optimisation.performed",
718 "upgrade-repo.optimisation.performed",
715 )
719 )
716 self.ui.write(b'\n\n')
720 self.ui.write(b'\n\n')
717
721
718 def print_upgrade_actions(self):
722 def print_upgrade_actions(self):
719 for a in self.upgrade_actions:
723 for a in self.upgrade_actions:
720 self.ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
724 self.ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
721
725
722 def print_affected_revlogs(self):
726 def print_affected_revlogs(self):
723 if not self.revlogs_to_process:
727 if not self.revlogs_to_process:
724 self.ui.write((b'no revlogs to process\n'))
728 self.ui.write((b'no revlogs to process\n'))
725 else:
729 else:
726 self.ui.write((b'processed revlogs:\n'))
730 self.ui.write((b'processed revlogs:\n'))
727 for r in sorted(self.revlogs_to_process):
731 for r in sorted(self.revlogs_to_process):
728 self.ui.write((b' - %s\n' % r))
732 self.ui.write((b' - %s\n' % r))
729 self.ui.write((b'\n'))
733 self.ui.write((b'\n'))
730
734
731 def print_unused_optimizations(self):
735 def print_unused_optimizations(self):
732 for i in self.unused_optimizations:
736 for i in self.unused_optimizations:
733 self.ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
737 self.ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
734
738
735 def has_upgrade_action(self, name):
739 def has_upgrade_action(self, name):
736 """ Check whether the upgrade operation will perform this action """
740 """ Check whether the upgrade operation will perform this action """
737 return name in self._upgrade_actions_names
741 return name in self._upgrade_actions_names
738
742
739 def print_post_op_messages(self):
743 def print_post_op_messages(self):
740 """ print post upgrade operation warning messages """
744 """ print post upgrade operation warning messages """
741 for a in self.upgrade_actions:
745 for a in self.upgrade_actions:
742 if a.postupgrademessage is not None:
746 if a.postupgrademessage is not None:
743 self.ui.warn(b'%s\n' % a.postupgrademessage)
747 self.ui.warn(b'%s\n' % a.postupgrademessage)
744 for a in self.removed_actions:
748 for a in self.removed_actions:
745 if a.postdowngrademessage is not None:
749 if a.postdowngrademessage is not None:
746 self.ui.warn(b'%s\n' % a.postdowngrademessage)
750 self.ui.warn(b'%s\n' % a.postdowngrademessage)
747
751
748
752
749 ### Code checking if a repository can got through the upgrade process at all. #
753 ### Code checking if a repository can got through the upgrade process at all. #
750
754
751
755
752 def requiredsourcerequirements(repo):
756 def requiredsourcerequirements(repo):
753 """Obtain requirements required to be present to upgrade a repo.
757 """Obtain requirements required to be present to upgrade a repo.
754
758
755 An upgrade will not be allowed if the repository doesn't have the
759 An upgrade will not be allowed if the repository doesn't have the
756 requirements returned by this function.
760 requirements returned by this function.
757 """
761 """
758 return {
762 return {
759 # Introduced in Mercurial 0.9.2.
763 # Introduced in Mercurial 0.9.2.
760 b'revlogv1',
764 b'revlogv1',
761 # Introduced in Mercurial 0.9.2.
765 # Introduced in Mercurial 0.9.2.
762 b'store',
766 b'store',
763 }
767 }
764
768
765
769
766 def blocksourcerequirements(repo):
770 def blocksourcerequirements(repo):
767 """Obtain requirements that will prevent an upgrade from occurring.
771 """Obtain requirements that will prevent an upgrade from occurring.
768
772
769 An upgrade cannot be performed if the source repository contains a
773 An upgrade cannot be performed if the source repository contains a
770 requirements in the returned set.
774 requirements in the returned set.
771 """
775 """
772 return {
776 return {
773 # The upgrade code does not yet support these experimental features.
777 # The upgrade code does not yet support these experimental features.
774 # This is an artificial limitation.
778 # This is an artificial limitation.
775 requirements.TREEMANIFEST_REQUIREMENT,
779 requirements.TREEMANIFEST_REQUIREMENT,
776 # This was a precursor to generaldelta and was never enabled by default.
780 # This was a precursor to generaldelta and was never enabled by default.
777 # It should (hopefully) not exist in the wild.
781 # It should (hopefully) not exist in the wild.
778 b'parentdelta',
782 b'parentdelta',
779 # Upgrade should operate on the actual store, not the shared link.
783 # Upgrade should operate on the actual store, not the shared link.
780 requirements.SHARED_REQUIREMENT,
784 requirements.SHARED_REQUIREMENT,
781 }
785 }
782
786
783
787
784 def check_source_requirements(repo):
788 def check_source_requirements(repo):
785 """Ensure that no existing requirements prevent the repository upgrade"""
789 """Ensure that no existing requirements prevent the repository upgrade"""
786
790
787 required = requiredsourcerequirements(repo)
791 required = requiredsourcerequirements(repo)
788 missingreqs = required - repo.requirements
792 missingreqs = required - repo.requirements
789 if missingreqs:
793 if missingreqs:
790 msg = _(b'cannot upgrade repository; requirement missing: %s')
794 msg = _(b'cannot upgrade repository; requirement missing: %s')
791 missingreqs = b', '.join(sorted(missingreqs))
795 missingreqs = b', '.join(sorted(missingreqs))
792 raise error.Abort(msg % missingreqs)
796 raise error.Abort(msg % missingreqs)
793
797
794 blocking = blocksourcerequirements(repo)
798 blocking = blocksourcerequirements(repo)
795 blockingreqs = blocking & repo.requirements
799 blockingreqs = blocking & repo.requirements
796 if blockingreqs:
800 if blockingreqs:
797 m = _(b'cannot upgrade repository; unsupported source requirement: %s')
801 m = _(b'cannot upgrade repository; unsupported source requirement: %s')
798 blockingreqs = b', '.join(sorted(blockingreqs))
802 blockingreqs = b', '.join(sorted(blockingreqs))
799 raise error.Abort(m % blockingreqs)
803 raise error.Abort(m % blockingreqs)
800
804
801
805
802 ### Verify the validity of the planned requirement changes ####################
806 ### Verify the validity of the planned requirement changes ####################
803
807
804
808
805 def supportremovedrequirements(repo):
809 def supportremovedrequirements(repo):
806 """Obtain requirements that can be removed during an upgrade.
810 """Obtain requirements that can be removed during an upgrade.
807
811
808 If an upgrade were to create a repository that dropped a requirement,
812 If an upgrade were to create a repository that dropped a requirement,
809 the dropped requirement must appear in the returned set for the upgrade
813 the dropped requirement must appear in the returned set for the upgrade
810 to be allowed.
814 to be allowed.
811 """
815 """
812 supported = {
816 supported = {
813 requirements.SPARSEREVLOG_REQUIREMENT,
817 requirements.SPARSEREVLOG_REQUIREMENT,
814 requirements.SIDEDATA_REQUIREMENT,
818 requirements.SIDEDATA_REQUIREMENT,
815 requirements.COPIESSDC_REQUIREMENT,
819 requirements.COPIESSDC_REQUIREMENT,
816 requirements.NODEMAP_REQUIREMENT,
820 requirements.NODEMAP_REQUIREMENT,
817 requirements.SHARESAFE_REQUIREMENT,
821 requirements.SHARESAFE_REQUIREMENT,
818 }
822 }
819 for name in compression.compengines:
823 for name in compression.compengines:
820 engine = compression.compengines[name]
824 engine = compression.compengines[name]
821 if engine.available() and engine.revlogheader():
825 if engine.available() and engine.revlogheader():
822 supported.add(b'exp-compression-%s' % name)
826 supported.add(b'exp-compression-%s' % name)
823 if engine.name() == b'zstd':
827 if engine.name() == b'zstd':
824 supported.add(b'revlog-compression-zstd')
828 supported.add(b'revlog-compression-zstd')
825 return supported
829 return supported
826
830
827
831
828 def supporteddestrequirements(repo):
832 def supporteddestrequirements(repo):
829 """Obtain requirements that upgrade supports in the destination.
833 """Obtain requirements that upgrade supports in the destination.
830
834
831 If the result of the upgrade would create requirements not in this set,
835 If the result of the upgrade would create requirements not in this set,
832 the upgrade is disallowed.
836 the upgrade is disallowed.
833
837
834 Extensions should monkeypatch this to add their custom requirements.
838 Extensions should monkeypatch this to add their custom requirements.
835 """
839 """
836 supported = {
840 supported = {
837 b'dotencode',
841 b'dotencode',
838 b'fncache',
842 b'fncache',
839 b'generaldelta',
843 b'generaldelta',
840 b'revlogv1',
844 b'revlogv1',
841 b'store',
845 b'store',
842 requirements.SPARSEREVLOG_REQUIREMENT,
846 requirements.SPARSEREVLOG_REQUIREMENT,
843 requirements.SIDEDATA_REQUIREMENT,
847 requirements.SIDEDATA_REQUIREMENT,
844 requirements.COPIESSDC_REQUIREMENT,
848 requirements.COPIESSDC_REQUIREMENT,
845 requirements.NODEMAP_REQUIREMENT,
849 requirements.NODEMAP_REQUIREMENT,
846 requirements.SHARESAFE_REQUIREMENT,
850 requirements.SHARESAFE_REQUIREMENT,
847 }
851 }
848 for name in compression.compengines:
852 for name in compression.compengines:
849 engine = compression.compengines[name]
853 engine = compression.compengines[name]
850 if engine.available() and engine.revlogheader():
854 if engine.available() and engine.revlogheader():
851 supported.add(b'exp-compression-%s' % name)
855 supported.add(b'exp-compression-%s' % name)
852 if engine.name() == b'zstd':
856 if engine.name() == b'zstd':
853 supported.add(b'revlog-compression-zstd')
857 supported.add(b'revlog-compression-zstd')
854 return supported
858 return supported
855
859
856
860
857 def allowednewrequirements(repo):
861 def allowednewrequirements(repo):
858 """Obtain requirements that can be added to a repository during upgrade.
862 """Obtain requirements that can be added to a repository during upgrade.
859
863
860 This is used to disallow proposed requirements from being added when
864 This is used to disallow proposed requirements from being added when
861 they weren't present before.
865 they weren't present before.
862
866
863 We use a list of allowed requirement additions instead of a list of known
867 We use a list of allowed requirement additions instead of a list of known
864 bad additions because the whitelist approach is safer and will prevent
868 bad additions because the whitelist approach is safer and will prevent
865 future, unknown requirements from accidentally being added.
869 future, unknown requirements from accidentally being added.
866 """
870 """
867 supported = {
871 supported = {
868 b'dotencode',
872 b'dotencode',
869 b'fncache',
873 b'fncache',
870 b'generaldelta',
874 b'generaldelta',
871 requirements.SPARSEREVLOG_REQUIREMENT,
875 requirements.SPARSEREVLOG_REQUIREMENT,
872 requirements.SIDEDATA_REQUIREMENT,
876 requirements.SIDEDATA_REQUIREMENT,
873 requirements.COPIESSDC_REQUIREMENT,
877 requirements.COPIESSDC_REQUIREMENT,
874 requirements.NODEMAP_REQUIREMENT,
878 requirements.NODEMAP_REQUIREMENT,
875 requirements.SHARESAFE_REQUIREMENT,
879 requirements.SHARESAFE_REQUIREMENT,
876 }
880 }
877 for name in compression.compengines:
881 for name in compression.compengines:
878 engine = compression.compengines[name]
882 engine = compression.compengines[name]
879 if engine.available() and engine.revlogheader():
883 if engine.available() and engine.revlogheader():
880 supported.add(b'exp-compression-%s' % name)
884 supported.add(b'exp-compression-%s' % name)
881 if engine.name() == b'zstd':
885 if engine.name() == b'zstd':
882 supported.add(b'revlog-compression-zstd')
886 supported.add(b'revlog-compression-zstd')
883 return supported
887 return supported
884
888
885
889
886 def check_requirements_changes(repo, new_reqs):
890 def check_requirements_changes(repo, new_reqs):
887 old_reqs = repo.requirements
891 old_reqs = repo.requirements
888
892
889 support_removal = supportremovedrequirements(repo)
893 support_removal = supportremovedrequirements(repo)
890 no_remove_reqs = old_reqs - new_reqs - support_removal
894 no_remove_reqs = old_reqs - new_reqs - support_removal
891 if no_remove_reqs:
895 if no_remove_reqs:
892 msg = _(b'cannot upgrade repository; requirement would be removed: %s')
896 msg = _(b'cannot upgrade repository; requirement would be removed: %s')
893 no_remove_reqs = b', '.join(sorted(no_remove_reqs))
897 no_remove_reqs = b', '.join(sorted(no_remove_reqs))
894 raise error.Abort(msg % no_remove_reqs)
898 raise error.Abort(msg % no_remove_reqs)
895
899
896 support_addition = allowednewrequirements(repo)
900 support_addition = allowednewrequirements(repo)
897 no_add_reqs = new_reqs - old_reqs - support_addition
901 no_add_reqs = new_reqs - old_reqs - support_addition
898 if no_add_reqs:
902 if no_add_reqs:
899 m = _(b'cannot upgrade repository; do not support adding requirement: ')
903 m = _(b'cannot upgrade repository; do not support adding requirement: ')
900 no_add_reqs = b', '.join(sorted(no_add_reqs))
904 no_add_reqs = b', '.join(sorted(no_add_reqs))
901 raise error.Abort(m + no_add_reqs)
905 raise error.Abort(m + no_add_reqs)
902
906
903 supported = supporteddestrequirements(repo)
907 supported = supporteddestrequirements(repo)
904 unsupported_reqs = new_reqs - supported
908 unsupported_reqs = new_reqs - supported
905 if unsupported_reqs:
909 if unsupported_reqs:
906 msg = _(
910 msg = _(
907 b'cannot upgrade repository; do not support destination '
911 b'cannot upgrade repository; do not support destination '
908 b'requirement: %s'
912 b'requirement: %s'
909 )
913 )
910 unsupported_reqs = b', '.join(sorted(unsupported_reqs))
914 unsupported_reqs = b', '.join(sorted(unsupported_reqs))
911 raise error.Abort(msg % unsupported_reqs)
915 raise error.Abort(msg % unsupported_reqs)
@@ -1,521 +1,533 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import stat
10 import stat
11
11
12 from ..i18n import _
12 from ..i18n import _
13 from ..pycompat import getattr
13 from ..pycompat import getattr
14 from .. import (
14 from .. import (
15 changelog,
15 changelog,
16 error,
16 error,
17 filelog,
17 filelog,
18 manifest,
18 manifest,
19 metadata,
19 metadata,
20 pycompat,
20 pycompat,
21 requirements,
21 requirements,
22 revlog,
22 revlog,
23 scmutil,
23 scmutil,
24 util,
24 util,
25 vfs as vfsmod,
25 vfs as vfsmod,
26 )
26 )
27
27
28
28
29 def _revlogfrompath(repo, path):
29 def _revlogfrompath(repo, path):
30 """Obtain a revlog from a repo path.
30 """Obtain a revlog from a repo path.
31
31
32 An instance of the appropriate class is returned.
32 An instance of the appropriate class is returned.
33 """
33 """
34 if path == b'00changelog.i':
34 if path == b'00changelog.i':
35 return changelog.changelog(repo.svfs)
35 return changelog.changelog(repo.svfs)
36 elif path.endswith(b'00manifest.i'):
36 elif path.endswith(b'00manifest.i'):
37 mandir = path[: -len(b'00manifest.i')]
37 mandir = path[: -len(b'00manifest.i')]
38 return manifest.manifestrevlog(repo.svfs, tree=mandir)
38 return manifest.manifestrevlog(repo.svfs, tree=mandir)
39 else:
39 else:
40 # reverse of "/".join(("data", path + ".i"))
40 # reverse of "/".join(("data", path + ".i"))
41 return filelog.filelog(repo.svfs, path[5:-2])
41 return filelog.filelog(repo.svfs, path[5:-2])
42
42
43
43
44 def _copyrevlog(tr, destrepo, oldrl, unencodedname):
44 def _copyrevlog(tr, destrepo, oldrl, unencodedname):
45 """copy all relevant files for `oldrl` into `destrepo` store
45 """copy all relevant files for `oldrl` into `destrepo` store
46
46
47 Files are copied "as is" without any transformation. The copy is performed
47 Files are copied "as is" without any transformation. The copy is performed
48 without extra checks. Callers are responsible for making sure the copied
48 without extra checks. Callers are responsible for making sure the copied
49 content is compatible with format of the destination repository.
49 content is compatible with format of the destination repository.
50 """
50 """
51 oldrl = getattr(oldrl, '_revlog', oldrl)
51 oldrl = getattr(oldrl, '_revlog', oldrl)
52 newrl = _revlogfrompath(destrepo, unencodedname)
52 newrl = _revlogfrompath(destrepo, unencodedname)
53 newrl = getattr(newrl, '_revlog', newrl)
53 newrl = getattr(newrl, '_revlog', newrl)
54
54
55 oldvfs = oldrl.opener
55 oldvfs = oldrl.opener
56 newvfs = newrl.opener
56 newvfs = newrl.opener
57 oldindex = oldvfs.join(oldrl.indexfile)
57 oldindex = oldvfs.join(oldrl.indexfile)
58 newindex = newvfs.join(newrl.indexfile)
58 newindex = newvfs.join(newrl.indexfile)
59 olddata = oldvfs.join(oldrl.datafile)
59 olddata = oldvfs.join(oldrl.datafile)
60 newdata = newvfs.join(newrl.datafile)
60 newdata = newvfs.join(newrl.datafile)
61
61
62 with newvfs(newrl.indexfile, b'w'):
62 with newvfs(newrl.indexfile, b'w'):
63 pass # create all the directories
63 pass # create all the directories
64
64
65 util.copyfile(oldindex, newindex)
65 util.copyfile(oldindex, newindex)
66 copydata = oldrl.opener.exists(oldrl.datafile)
66 copydata = oldrl.opener.exists(oldrl.datafile)
67 if copydata:
67 if copydata:
68 util.copyfile(olddata, newdata)
68 util.copyfile(olddata, newdata)
69
69
70 if not (
70 if not (
71 unencodedname.endswith(b'00changelog.i')
71 unencodedname.endswith(b'00changelog.i')
72 or unencodedname.endswith(b'00manifest.i')
72 or unencodedname.endswith(b'00manifest.i')
73 ):
73 ):
74 destrepo.svfs.fncache.add(unencodedname)
74 destrepo.svfs.fncache.add(unencodedname)
75 if copydata:
75 if copydata:
76 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
76 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
77
77
78
78
79 UPGRADE_CHANGELOG = b"changelog"
79 UPGRADE_CHANGELOG = b"changelog"
80 UPGRADE_MANIFEST = b"manifest"
80 UPGRADE_MANIFEST = b"manifest"
81 UPGRADE_FILELOGS = b"all-filelogs"
81 UPGRADE_FILELOGS = b"all-filelogs"
82
82
83 UPGRADE_ALL_REVLOGS = frozenset(
83 UPGRADE_ALL_REVLOGS = frozenset(
84 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
84 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
85 )
85 )
86
86
87
87
88 def getsidedatacompanion(srcrepo, dstrepo):
88 def getsidedatacompanion(srcrepo, dstrepo):
89 sidedatacompanion = None
89 sidedatacompanion = None
90 removedreqs = srcrepo.requirements - dstrepo.requirements
90 removedreqs = srcrepo.requirements - dstrepo.requirements
91 addedreqs = dstrepo.requirements - srcrepo.requirements
91 addedreqs = dstrepo.requirements - srcrepo.requirements
92 if requirements.SIDEDATA_REQUIREMENT in removedreqs:
92 if requirements.SIDEDATA_REQUIREMENT in removedreqs:
93
93
94 def sidedatacompanion(rl, rev):
94 def sidedatacompanion(rl, rev):
95 rl = getattr(rl, '_revlog', rl)
95 rl = getattr(rl, '_revlog', rl)
96 if rl.flags(rev) & revlog.REVIDX_SIDEDATA:
96 if rl.flags(rev) & revlog.REVIDX_SIDEDATA:
97 return True, (), {}, 0, 0
97 return True, (), {}, 0, 0
98 return False, (), {}, 0, 0
98 return False, (), {}, 0, 0
99
99
100 elif requirements.COPIESSDC_REQUIREMENT in addedreqs:
100 elif requirements.COPIESSDC_REQUIREMENT in addedreqs:
101 sidedatacompanion = metadata.getsidedataadder(srcrepo, dstrepo)
101 sidedatacompanion = metadata.getsidedataadder(srcrepo, dstrepo)
102 elif requirements.COPIESSDC_REQUIREMENT in removedreqs:
102 elif requirements.COPIESSDC_REQUIREMENT in removedreqs:
103 sidedatacompanion = metadata.getsidedataremover(srcrepo, dstrepo)
103 sidedatacompanion = metadata.getsidedataremover(srcrepo, dstrepo)
104 return sidedatacompanion
104 return sidedatacompanion
105
105
106
106
107 def matchrevlog(revlogfilter, entry):
107 def matchrevlog(revlogfilter, entry):
108 """check if a revlog is selected for cloning.
108 """check if a revlog is selected for cloning.
109
109
110 In other words, are there any updates which need to be done on revlog
110 In other words, are there any updates which need to be done on revlog
111 or it can be blindly copied.
111 or it can be blindly copied.
112
112
113 The store entry is checked against the passed filter"""
113 The store entry is checked against the passed filter"""
114 if entry.endswith(b'00changelog.i'):
114 if entry.endswith(b'00changelog.i'):
115 return UPGRADE_CHANGELOG in revlogfilter
115 return UPGRADE_CHANGELOG in revlogfilter
116 elif entry.endswith(b'00manifest.i'):
116 elif entry.endswith(b'00manifest.i'):
117 return UPGRADE_MANIFEST in revlogfilter
117 return UPGRADE_MANIFEST in revlogfilter
118 return UPGRADE_FILELOGS in revlogfilter
118 return UPGRADE_FILELOGS in revlogfilter
119
119
120
120
121 def _perform_clone(
121 def _perform_clone(
122 ui,
122 ui,
123 dstrepo,
123 dstrepo,
124 tr,
124 tr,
125 old_revlog,
125 old_revlog,
126 unencoded,
126 unencoded,
127 upgrade_op,
127 upgrade_op,
128 sidedatacompanion,
128 sidedatacompanion,
129 oncopiedrevision,
129 oncopiedrevision,
130 ):
130 ):
131 """ returns the new revlog object created"""
131 """ returns the new revlog object created"""
132 newrl = None
132 newrl = None
133 if matchrevlog(upgrade_op.revlogs_to_process, unencoded):
133 if matchrevlog(upgrade_op.revlogs_to_process, unencoded):
134 ui.note(
134 ui.note(
135 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
135 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
136 )
136 )
137 newrl = _revlogfrompath(dstrepo, unencoded)
137 newrl = _revlogfrompath(dstrepo, unencoded)
138 old_revlog.clone(
138 old_revlog.clone(
139 tr,
139 tr,
140 newrl,
140 newrl,
141 addrevisioncb=oncopiedrevision,
141 addrevisioncb=oncopiedrevision,
142 deltareuse=upgrade_op.delta_reuse_mode,
142 deltareuse=upgrade_op.delta_reuse_mode,
143 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
143 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
144 sidedatacompanion=sidedatacompanion,
144 sidedatacompanion=sidedatacompanion,
145 )
145 )
146 else:
146 else:
147 msg = _(b'blindly copying %s containing %i revisions\n')
147 msg = _(b'blindly copying %s containing %i revisions\n')
148 ui.note(msg % (unencoded, len(old_revlog)))
148 ui.note(msg % (unencoded, len(old_revlog)))
149 _copyrevlog(tr, dstrepo, old_revlog, unencoded)
149 _copyrevlog(tr, dstrepo, old_revlog, unencoded)
150
150
151 newrl = _revlogfrompath(dstrepo, unencoded)
151 newrl = _revlogfrompath(dstrepo, unencoded)
152 return newrl
152 return newrl
153
153
154
154
155 def _clonerevlogs(
155 def _clonerevlogs(
156 ui,
156 ui,
157 srcrepo,
157 srcrepo,
158 dstrepo,
158 dstrepo,
159 tr,
159 tr,
160 upgrade_op,
160 upgrade_op,
161 ):
161 ):
162 """Copy revlogs between 2 repos."""
162 """Copy revlogs between 2 repos."""
163 revcount = 0
163 revcount = 0
164 srcsize = 0
164 srcsize = 0
165 srcrawsize = 0
165 srcrawsize = 0
166 dstsize = 0
166 dstsize = 0
167 fcount = 0
167 fcount = 0
168 frevcount = 0
168 frevcount = 0
169 fsrcsize = 0
169 fsrcsize = 0
170 frawsize = 0
170 frawsize = 0
171 fdstsize = 0
171 fdstsize = 0
172 mcount = 0
172 mcount = 0
173 mrevcount = 0
173 mrevcount = 0
174 msrcsize = 0
174 msrcsize = 0
175 mrawsize = 0
175 mrawsize = 0
176 mdstsize = 0
176 mdstsize = 0
177 crevcount = 0
177 crevcount = 0
178 csrcsize = 0
178 csrcsize = 0
179 crawsize = 0
179 crawsize = 0
180 cdstsize = 0
180 cdstsize = 0
181
181
182 alldatafiles = list(srcrepo.store.walk())
182 alldatafiles = list(srcrepo.store.walk())
183 # mapping of data files which needs to be cloned
183 # mapping of data files which needs to be cloned
184 # key is unencoded filename
184 # key is unencoded filename
185 # value is revlog_object_from_srcrepo
185 # value is revlog_object_from_srcrepo
186 manifests = {}
186 manifests = {}
187 changelogs = {}
187 changelogs = {}
188 filelogs = {}
188 filelogs = {}
189
189
190 # Perform a pass to collect metadata. This validates we can open all
190 # Perform a pass to collect metadata. This validates we can open all
191 # source files and allows a unified progress bar to be displayed.
191 # source files and allows a unified progress bar to be displayed.
192 for unencoded, encoded, size in alldatafiles:
192 for unencoded, encoded, size in alldatafiles:
193 if not unencoded.endswith(b'.i'):
193 if not unencoded.endswith(b'.i'):
194 continue
194 continue
195
195
196 rl = _revlogfrompath(srcrepo, unencoded)
196 rl = _revlogfrompath(srcrepo, unencoded)
197
197
198 info = rl.storageinfo(
198 info = rl.storageinfo(
199 exclusivefiles=True,
199 exclusivefiles=True,
200 revisionscount=True,
200 revisionscount=True,
201 trackedsize=True,
201 trackedsize=True,
202 storedsize=True,
202 storedsize=True,
203 )
203 )
204
204
205 revcount += info[b'revisionscount'] or 0
205 revcount += info[b'revisionscount'] or 0
206 datasize = info[b'storedsize'] or 0
206 datasize = info[b'storedsize'] or 0
207 rawsize = info[b'trackedsize'] or 0
207 rawsize = info[b'trackedsize'] or 0
208
208
209 srcsize += datasize
209 srcsize += datasize
210 srcrawsize += rawsize
210 srcrawsize += rawsize
211
211
212 # This is for the separate progress bars.
212 # This is for the separate progress bars.
213 if isinstance(rl, changelog.changelog):
213 if isinstance(rl, changelog.changelog):
214 changelogs[unencoded] = rl
214 changelogs[unencoded] = rl
215 crevcount += len(rl)
215 crevcount += len(rl)
216 csrcsize += datasize
216 csrcsize += datasize
217 crawsize += rawsize
217 crawsize += rawsize
218 elif isinstance(rl, manifest.manifestrevlog):
218 elif isinstance(rl, manifest.manifestrevlog):
219 manifests[unencoded] = rl
219 manifests[unencoded] = rl
220 mcount += 1
220 mcount += 1
221 mrevcount += len(rl)
221 mrevcount += len(rl)
222 msrcsize += datasize
222 msrcsize += datasize
223 mrawsize += rawsize
223 mrawsize += rawsize
224 elif isinstance(rl, filelog.filelog):
224 elif isinstance(rl, filelog.filelog):
225 filelogs[unencoded] = rl
225 filelogs[unencoded] = rl
226 fcount += 1
226 fcount += 1
227 frevcount += len(rl)
227 frevcount += len(rl)
228 fsrcsize += datasize
228 fsrcsize += datasize
229 frawsize += rawsize
229 frawsize += rawsize
230 else:
230 else:
231 error.ProgrammingError(b'unknown revlog type')
231 error.ProgrammingError(b'unknown revlog type')
232
232
233 if not revcount:
233 if not revcount:
234 return
234 return
235
235
236 ui.status(
236 ui.status(
237 _(
237 _(
238 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
238 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
239 b'%d in changelog)\n'
239 b'%d in changelog)\n'
240 )
240 )
241 % (revcount, frevcount, mrevcount, crevcount)
241 % (revcount, frevcount, mrevcount, crevcount)
242 )
242 )
243 ui.status(
243 ui.status(
244 _(b'migrating %s in store; %s tracked data\n')
244 _(b'migrating %s in store; %s tracked data\n')
245 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
245 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
246 )
246 )
247
247
248 # Used to keep track of progress.
248 # Used to keep track of progress.
249 progress = None
249 progress = None
250
250
251 def oncopiedrevision(rl, rev, node):
251 def oncopiedrevision(rl, rev, node):
252 progress.increment()
252 progress.increment()
253
253
254 sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
254 sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
255
255
256 # Migrating filelogs
256 # Migrating filelogs
257 ui.status(
257 ui.status(
258 _(
258 _(
259 b'migrating %d filelogs containing %d revisions '
259 b'migrating %d filelogs containing %d revisions '
260 b'(%s in store; %s tracked data)\n'
260 b'(%s in store; %s tracked data)\n'
261 )
261 )
262 % (
262 % (
263 fcount,
263 fcount,
264 frevcount,
264 frevcount,
265 util.bytecount(fsrcsize),
265 util.bytecount(fsrcsize),
266 util.bytecount(frawsize),
266 util.bytecount(frawsize),
267 )
267 )
268 )
268 )
269 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
269 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
270 for unencoded, oldrl in sorted(filelogs.items()):
270 for unencoded, oldrl in sorted(filelogs.items()):
271 newrl = _perform_clone(
271 newrl = _perform_clone(
272 ui,
272 ui,
273 dstrepo,
273 dstrepo,
274 tr,
274 tr,
275 oldrl,
275 oldrl,
276 unencoded,
276 unencoded,
277 upgrade_op,
277 upgrade_op,
278 sidedatacompanion,
278 sidedatacompanion,
279 oncopiedrevision,
279 oncopiedrevision,
280 )
280 )
281 info = newrl.storageinfo(storedsize=True)
281 info = newrl.storageinfo(storedsize=True)
282 fdstsize += info[b'storedsize'] or 0
282 fdstsize += info[b'storedsize'] or 0
283 ui.status(
283 ui.status(
284 _(
284 _(
285 b'finished migrating %d filelog revisions across %d '
285 b'finished migrating %d filelog revisions across %d '
286 b'filelogs; change in size: %s\n'
286 b'filelogs; change in size: %s\n'
287 )
287 )
288 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
288 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
289 )
289 )
290
290
291 # Migrating manifests
291 # Migrating manifests
292 ui.status(
292 ui.status(
293 _(
293 _(
294 b'migrating %d manifests containing %d revisions '
294 b'migrating %d manifests containing %d revisions '
295 b'(%s in store; %s tracked data)\n'
295 b'(%s in store; %s tracked data)\n'
296 )
296 )
297 % (
297 % (
298 mcount,
298 mcount,
299 mrevcount,
299 mrevcount,
300 util.bytecount(msrcsize),
300 util.bytecount(msrcsize),
301 util.bytecount(mrawsize),
301 util.bytecount(mrawsize),
302 )
302 )
303 )
303 )
304 if progress:
304 if progress:
305 progress.complete()
305 progress.complete()
306 progress = srcrepo.ui.makeprogress(
306 progress = srcrepo.ui.makeprogress(
307 _(b'manifest revisions'), total=mrevcount
307 _(b'manifest revisions'), total=mrevcount
308 )
308 )
309 for unencoded, oldrl in sorted(manifests.items()):
309 for unencoded, oldrl in sorted(manifests.items()):
310 newrl = _perform_clone(
310 newrl = _perform_clone(
311 ui,
311 ui,
312 dstrepo,
312 dstrepo,
313 tr,
313 tr,
314 oldrl,
314 oldrl,
315 unencoded,
315 unencoded,
316 upgrade_op,
316 upgrade_op,
317 sidedatacompanion,
317 sidedatacompanion,
318 oncopiedrevision,
318 oncopiedrevision,
319 )
319 )
320 info = newrl.storageinfo(storedsize=True)
320 info = newrl.storageinfo(storedsize=True)
321 mdstsize += info[b'storedsize'] or 0
321 mdstsize += info[b'storedsize'] or 0
322 ui.status(
322 ui.status(
323 _(
323 _(
324 b'finished migrating %d manifest revisions across %d '
324 b'finished migrating %d manifest revisions across %d '
325 b'manifests; change in size: %s\n'
325 b'manifests; change in size: %s\n'
326 )
326 )
327 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
327 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
328 )
328 )
329
329
330 # Migrating changelog
330 # Migrating changelog
331 ui.status(
331 ui.status(
332 _(
332 _(
333 b'migrating changelog containing %d revisions '
333 b'migrating changelog containing %d revisions '
334 b'(%s in store; %s tracked data)\n'
334 b'(%s in store; %s tracked data)\n'
335 )
335 )
336 % (
336 % (
337 crevcount,
337 crevcount,
338 util.bytecount(csrcsize),
338 util.bytecount(csrcsize),
339 util.bytecount(crawsize),
339 util.bytecount(crawsize),
340 )
340 )
341 )
341 )
342 if progress:
342 if progress:
343 progress.complete()
343 progress.complete()
344 progress = srcrepo.ui.makeprogress(
344 progress = srcrepo.ui.makeprogress(
345 _(b'changelog revisions'), total=crevcount
345 _(b'changelog revisions'), total=crevcount
346 )
346 )
347 for unencoded, oldrl in sorted(changelogs.items()):
347 for unencoded, oldrl in sorted(changelogs.items()):
348 newrl = _perform_clone(
348 newrl = _perform_clone(
349 ui,
349 ui,
350 dstrepo,
350 dstrepo,
351 tr,
351 tr,
352 oldrl,
352 oldrl,
353 unencoded,
353 unencoded,
354 upgrade_op,
354 upgrade_op,
355 sidedatacompanion,
355 sidedatacompanion,
356 oncopiedrevision,
356 oncopiedrevision,
357 )
357 )
358 info = newrl.storageinfo(storedsize=True)
358 info = newrl.storageinfo(storedsize=True)
359 cdstsize += info[b'storedsize'] or 0
359 cdstsize += info[b'storedsize'] or 0
360 progress.complete()
360 progress.complete()
361 ui.status(
361 ui.status(
362 _(
362 _(
363 b'finished migrating %d changelog revisions; change in size: '
363 b'finished migrating %d changelog revisions; change in size: '
364 b'%s\n'
364 b'%s\n'
365 )
365 )
366 % (crevcount, util.bytecount(cdstsize - csrcsize))
366 % (crevcount, util.bytecount(cdstsize - csrcsize))
367 )
367 )
368
368
369 dstsize = fdstsize + mdstsize + cdstsize
369 dstsize = fdstsize + mdstsize + cdstsize
370 ui.status(
370 ui.status(
371 _(
371 _(
372 b'finished migrating %d total revisions; total change in store '
372 b'finished migrating %d total revisions; total change in store '
373 b'size: %s\n'
373 b'size: %s\n'
374 )
374 )
375 % (revcount, util.bytecount(dstsize - srcsize))
375 % (revcount, util.bytecount(dstsize - srcsize))
376 )
376 )
377
377
378
378
379 def _files_to_copy_post_revlog_clone(srcrepo):
379 def _files_to_copy_post_revlog_clone(srcrepo):
380 """yields files which should be copied to destination after revlogs
380 """yields files which should be copied to destination after revlogs
381 are cloned"""
381 are cloned"""
382 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
382 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
383 # don't copy revlogs as they are already cloned
383 # don't copy revlogs as they are already cloned
384 if path.endswith((b'.i', b'.d', b'.n', b'.nd')):
384 if path.endswith((b'.i', b'.d', b'.n', b'.nd')):
385 continue
385 continue
386 # Skip transaction related files.
386 # Skip transaction related files.
387 if path.startswith(b'undo'):
387 if path.startswith(b'undo'):
388 continue
388 continue
389 # Only copy regular files.
389 # Only copy regular files.
390 if kind != stat.S_IFREG:
390 if kind != stat.S_IFREG:
391 continue
391 continue
392 # Skip other skipped files.
392 # Skip other skipped files.
393 if path in (b'lock', b'fncache'):
393 if path in (b'lock', b'fncache'):
394 continue
394 continue
395 # TODO: should we skip cache too?
395 # TODO: should we skip cache too?
396
396
397 yield path
397 yield path
398
398
399
399
400 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
400 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
401 """Replace the stores after current repository is upgraded
401 """Replace the stores after current repository is upgraded
402
402
403 Creates a backup of current repository store at backup path
403 Creates a backup of current repository store at backup path
404 Replaces upgraded store files in current repo from upgraded one
404 Replaces upgraded store files in current repo from upgraded one
405
405
406 Arguments:
406 Arguments:
407 currentrepo: repo object of current repository
407 currentrepo: repo object of current repository
408 upgradedrepo: repo object of the upgraded data
408 upgradedrepo: repo object of the upgraded data
409 backupvfs: vfs object for the backup path
409 backupvfs: vfs object for the backup path
410 upgrade_op: upgrade operation object
410 upgrade_op: upgrade operation object
411 to be used to decide what all is upgraded
411 to be used to decide what all is upgraded
412 """
412 """
413 # TODO: don't blindly rename everything in store
413 # TODO: don't blindly rename everything in store
414 # There can be upgrades where store is not touched at all
414 # There can be upgrades where store is not touched at all
415 util.rename(currentrepo.spath, backupvfs.join(b'store'))
415 if upgrade_op.backup_store:
416 util.rename(currentrepo.spath, backupvfs.join(b'store'))
417 else:
418 currentrepo.vfs.rmtree(b'store', forcibly=True)
416 util.rename(upgradedrepo.spath, currentrepo.spath)
419 util.rename(upgradedrepo.spath, currentrepo.spath)
417
420
418
421
419 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
422 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
420 """Hook point for extensions to perform additional actions during upgrade.
423 """Hook point for extensions to perform additional actions during upgrade.
421
424
422 This function is called after revlogs and store files have been copied but
425 This function is called after revlogs and store files have been copied but
423 before the new store is swapped into the original location.
426 before the new store is swapped into the original location.
424 """
427 """
425
428
426
429
427 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
430 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
428 """Do the low-level work of upgrading a repository.
431 """Do the low-level work of upgrading a repository.
429
432
430 The upgrade is effectively performed as a copy between a source
433 The upgrade is effectively performed as a copy between a source
431 repository and a temporary destination repository.
434 repository and a temporary destination repository.
432
435
433 The source repository is unmodified for as long as possible so the
436 The source repository is unmodified for as long as possible so the
434 upgrade can abort at any time without causing loss of service for
437 upgrade can abort at any time without causing loss of service for
435 readers and without corrupting the source repository.
438 readers and without corrupting the source repository.
436 """
439 """
437 assert srcrepo.currentwlock()
440 assert srcrepo.currentwlock()
438 assert dstrepo.currentwlock()
441 assert dstrepo.currentwlock()
442 backuppath = None
443 backupvfs = None
439
444
440 ui.status(
445 ui.status(
441 _(
446 _(
442 b'(it is safe to interrupt this process any time before '
447 b'(it is safe to interrupt this process any time before '
443 b'data migration completes)\n'
448 b'data migration completes)\n'
444 )
449 )
445 )
450 )
446
451
447 with dstrepo.transaction(b'upgrade') as tr:
452 with dstrepo.transaction(b'upgrade') as tr:
448 _clonerevlogs(
453 _clonerevlogs(
449 ui,
454 ui,
450 srcrepo,
455 srcrepo,
451 dstrepo,
456 dstrepo,
452 tr,
457 tr,
453 upgrade_op,
458 upgrade_op,
454 )
459 )
455
460
456 # Now copy other files in the store directory.
461 # Now copy other files in the store directory.
457 for p in _files_to_copy_post_revlog_clone(srcrepo):
462 for p in _files_to_copy_post_revlog_clone(srcrepo):
458 srcrepo.ui.status(_(b'copying %s\n') % p)
463 srcrepo.ui.status(_(b'copying %s\n') % p)
459 src = srcrepo.store.rawvfs.join(p)
464 src = srcrepo.store.rawvfs.join(p)
460 dst = dstrepo.store.rawvfs.join(p)
465 dst = dstrepo.store.rawvfs.join(p)
461 util.copyfile(src, dst, copystat=True)
466 util.copyfile(src, dst, copystat=True)
462
467
463 finishdatamigration(ui, srcrepo, dstrepo, requirements)
468 finishdatamigration(ui, srcrepo, dstrepo, requirements)
464
469
465 ui.status(_(b'data fully upgraded in a temporary repository\n'))
470 ui.status(_(b'data fully upgraded in a temporary repository\n'))
466
471
467 backuppath = pycompat.mkdtemp(prefix=b'upgradebackup.', dir=srcrepo.path)
472 if upgrade_op.backup_store:
468 backupvfs = vfsmod.vfs(backuppath)
473 backuppath = pycompat.mkdtemp(
474 prefix=b'upgradebackup.', dir=srcrepo.path
475 )
476 backupvfs = vfsmod.vfs(backuppath)
469
477
470 # Make a backup of requires file first, as it is the first to be modified.
478 # Make a backup of requires file first, as it is the first to be modified.
471 util.copyfile(srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires'))
479 util.copyfile(
480 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
481 )
472
482
473 # We install an arbitrary requirement that clients must not support
483 # We install an arbitrary requirement that clients must not support
474 # as a mechanism to lock out new clients during the data swap. This is
484 # as a mechanism to lock out new clients during the data swap. This is
475 # better than allowing a client to continue while the repository is in
485 # better than allowing a client to continue while the repository is in
476 # an inconsistent state.
486 # an inconsistent state.
477 ui.status(
487 ui.status(
478 _(
488 _(
479 b'marking source repository as being upgraded; clients will be '
489 b'marking source repository as being upgraded; clients will be '
480 b'unable to read from repository\n'
490 b'unable to read from repository\n'
481 )
491 )
482 )
492 )
483 scmutil.writereporequirements(
493 scmutil.writereporequirements(
484 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
494 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
485 )
495 )
486
496
487 ui.status(_(b'starting in-place swap of repository data\n'))
497 ui.status(_(b'starting in-place swap of repository data\n'))
488 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
498 if upgrade_op.backup_store:
499 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
489
500
490 # Now swap in the new store directory. Doing it as a rename should make
501 # Now swap in the new store directory. Doing it as a rename should make
491 # the operation nearly instantaneous and atomic (at least in well-behaved
502 # the operation nearly instantaneous and atomic (at least in well-behaved
492 # environments).
503 # environments).
493 ui.status(_(b'replacing store...\n'))
504 ui.status(_(b'replacing store...\n'))
494 tstart = util.timer()
505 tstart = util.timer()
495 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
506 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
496 elapsed = util.timer() - tstart
507 elapsed = util.timer() - tstart
497 ui.status(
508 ui.status(
498 _(
509 _(
499 b'store replacement complete; repository was inconsistent for '
510 b'store replacement complete; repository was inconsistent for '
500 b'%0.1fs\n'
511 b'%0.1fs\n'
501 )
512 )
502 % elapsed
513 % elapsed
503 )
514 )
504
515
505 # We first write the requirements file. Any new requirements will lock
516 # We first write the requirements file. Any new requirements will lock
506 # out legacy clients.
517 # out legacy clients.
507 ui.status(
518 ui.status(
508 _(
519 _(
509 b'finalizing requirements file and making repository readable '
520 b'finalizing requirements file and making repository readable '
510 b'again\n'
521 b'again\n'
511 )
522 )
512 )
523 )
513 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
524 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
514
525
515 # The lock file from the old store won't be removed because nothing has a
526 if upgrade_op.backup_store:
516 # reference to its new location. So clean it up manually. Alternatively, we
527 # The lock file from the old store won't be removed because nothing has a
517 # could update srcrepo.svfs and other variables to point to the new
528 # reference to its new location. So clean it up manually. Alternatively, we
518 # location. This is simpler.
529 # could update srcrepo.svfs and other variables to point to the new
519 backupvfs.unlink(b'store/lock')
530 # location. This is simpler.
531 backupvfs.unlink(b'store/lock')
520
532
521 return backuppath
533 return backuppath
@@ -1,1527 +1,1513 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > share =
5 > share =
6 > EOF
6 > EOF
7
7
8 store and revlogv1 are required in source
8 store and revlogv1 are required in source
9
9
10 $ hg --config format.usestore=false init no-store
10 $ hg --config format.usestore=false init no-store
11 $ hg -R no-store debugupgraderepo
11 $ hg -R no-store debugupgraderepo
12 abort: cannot upgrade repository; requirement missing: store
12 abort: cannot upgrade repository; requirement missing: store
13 [255]
13 [255]
14
14
15 $ hg init no-revlogv1
15 $ hg init no-revlogv1
16 $ cat > no-revlogv1/.hg/requires << EOF
16 $ cat > no-revlogv1/.hg/requires << EOF
17 > dotencode
17 > dotencode
18 > fncache
18 > fncache
19 > generaldelta
19 > generaldelta
20 > store
20 > store
21 > EOF
21 > EOF
22
22
23 $ hg -R no-revlogv1 debugupgraderepo
23 $ hg -R no-revlogv1 debugupgraderepo
24 abort: cannot upgrade repository; requirement missing: revlogv1
24 abort: cannot upgrade repository; requirement missing: revlogv1
25 [255]
25 [255]
26
26
27 Cannot upgrade shared repositories
27 Cannot upgrade shared repositories
28
28
29 $ hg init share-parent
29 $ hg init share-parent
30 $ hg -q share share-parent share-child
30 $ hg -q share share-parent share-child
31
31
32 $ hg -R share-child debugupgraderepo
32 $ hg -R share-child debugupgraderepo
33 abort: cannot upgrade repository; unsupported source requirement: shared
33 abort: cannot upgrade repository; unsupported source requirement: shared
34 [255]
34 [255]
35
35
36 Do not yet support upgrading treemanifest repos
36 Do not yet support upgrading treemanifest repos
37
37
38 $ hg --config experimental.treemanifest=true init treemanifest
38 $ hg --config experimental.treemanifest=true init treemanifest
39 $ hg -R treemanifest debugupgraderepo
39 $ hg -R treemanifest debugupgraderepo
40 abort: cannot upgrade repository; unsupported source requirement: treemanifest
40 abort: cannot upgrade repository; unsupported source requirement: treemanifest
41 [255]
41 [255]
42
42
43 Cannot add treemanifest requirement during upgrade
43 Cannot add treemanifest requirement during upgrade
44
44
45 $ hg init disallowaddedreq
45 $ hg init disallowaddedreq
46 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
46 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
47 abort: cannot upgrade repository; do not support adding requirement: treemanifest
47 abort: cannot upgrade repository; do not support adding requirement: treemanifest
48 [255]
48 [255]
49
49
50 An upgrade of a repository created with recommended settings only suggests optimizations
50 An upgrade of a repository created with recommended settings only suggests optimizations
51
51
52 $ hg init empty
52 $ hg init empty
53 $ cd empty
53 $ cd empty
54 $ hg debugformat
54 $ hg debugformat
55 format-variant repo
55 format-variant repo
56 fncache: yes
56 fncache: yes
57 dotencode: yes
57 dotencode: yes
58 generaldelta: yes
58 generaldelta: yes
59 share-safe: no
59 share-safe: no
60 sparserevlog: yes
60 sparserevlog: yes
61 sidedata: no
61 sidedata: no
62 persistent-nodemap: no
62 persistent-nodemap: no
63 copies-sdc: no
63 copies-sdc: no
64 plain-cl-delta: yes
64 plain-cl-delta: yes
65 compression: zlib
65 compression: zlib
66 compression-level: default
66 compression-level: default
67 $ hg debugformat --verbose
67 $ hg debugformat --verbose
68 format-variant repo config default
68 format-variant repo config default
69 fncache: yes yes yes
69 fncache: yes yes yes
70 dotencode: yes yes yes
70 dotencode: yes yes yes
71 generaldelta: yes yes yes
71 generaldelta: yes yes yes
72 share-safe: no no no
72 share-safe: no no no
73 sparserevlog: yes yes yes
73 sparserevlog: yes yes yes
74 sidedata: no no no
74 sidedata: no no no
75 persistent-nodemap: no no no
75 persistent-nodemap: no no no
76 copies-sdc: no no no
76 copies-sdc: no no no
77 plain-cl-delta: yes yes yes
77 plain-cl-delta: yes yes yes
78 compression: zlib zlib zlib
78 compression: zlib zlib zlib
79 compression-level: default default default
79 compression-level: default default default
80 $ hg debugformat --verbose --config format.usefncache=no
80 $ hg debugformat --verbose --config format.usefncache=no
81 format-variant repo config default
81 format-variant repo config default
82 fncache: yes no yes
82 fncache: yes no yes
83 dotencode: yes no yes
83 dotencode: yes no yes
84 generaldelta: yes yes yes
84 generaldelta: yes yes yes
85 share-safe: no no no
85 share-safe: no no no
86 sparserevlog: yes yes yes
86 sparserevlog: yes yes yes
87 sidedata: no no no
87 sidedata: no no no
88 persistent-nodemap: no no no
88 persistent-nodemap: no no no
89 copies-sdc: no no no
89 copies-sdc: no no no
90 plain-cl-delta: yes yes yes
90 plain-cl-delta: yes yes yes
91 compression: zlib zlib zlib
91 compression: zlib zlib zlib
92 compression-level: default default default
92 compression-level: default default default
93 $ hg debugformat --verbose --config format.usefncache=no --color=debug
93 $ hg debugformat --verbose --config format.usefncache=no --color=debug
94 format-variant repo config default
94 format-variant repo config default
95 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
95 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
96 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
96 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
97 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
97 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
98 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
98 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
99 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
99 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
100 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
100 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
101 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
101 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
102 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
102 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
103 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
103 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
104 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
104 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
105 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
105 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
106 $ hg debugformat -Tjson
106 $ hg debugformat -Tjson
107 [
107 [
108 {
108 {
109 "config": true,
109 "config": true,
110 "default": true,
110 "default": true,
111 "name": "fncache",
111 "name": "fncache",
112 "repo": true
112 "repo": true
113 },
113 },
114 {
114 {
115 "config": true,
115 "config": true,
116 "default": true,
116 "default": true,
117 "name": "dotencode",
117 "name": "dotencode",
118 "repo": true
118 "repo": true
119 },
119 },
120 {
120 {
121 "config": true,
121 "config": true,
122 "default": true,
122 "default": true,
123 "name": "generaldelta",
123 "name": "generaldelta",
124 "repo": true
124 "repo": true
125 },
125 },
126 {
126 {
127 "config": false,
127 "config": false,
128 "default": false,
128 "default": false,
129 "name": "share-safe",
129 "name": "share-safe",
130 "repo": false
130 "repo": false
131 },
131 },
132 {
132 {
133 "config": true,
133 "config": true,
134 "default": true,
134 "default": true,
135 "name": "sparserevlog",
135 "name": "sparserevlog",
136 "repo": true
136 "repo": true
137 },
137 },
138 {
138 {
139 "config": false,
139 "config": false,
140 "default": false,
140 "default": false,
141 "name": "sidedata",
141 "name": "sidedata",
142 "repo": false
142 "repo": false
143 },
143 },
144 {
144 {
145 "config": false,
145 "config": false,
146 "default": false,
146 "default": false,
147 "name": "persistent-nodemap",
147 "name": "persistent-nodemap",
148 "repo": false
148 "repo": false
149 },
149 },
150 {
150 {
151 "config": false,
151 "config": false,
152 "default": false,
152 "default": false,
153 "name": "copies-sdc",
153 "name": "copies-sdc",
154 "repo": false
154 "repo": false
155 },
155 },
156 {
156 {
157 "config": true,
157 "config": true,
158 "default": true,
158 "default": true,
159 "name": "plain-cl-delta",
159 "name": "plain-cl-delta",
160 "repo": true
160 "repo": true
161 },
161 },
162 {
162 {
163 "config": "zlib",
163 "config": "zlib",
164 "default": "zlib",
164 "default": "zlib",
165 "name": "compression",
165 "name": "compression",
166 "repo": "zlib"
166 "repo": "zlib"
167 },
167 },
168 {
168 {
169 "config": "default",
169 "config": "default",
170 "default": "default",
170 "default": "default",
171 "name": "compression-level",
171 "name": "compression-level",
172 "repo": "default"
172 "repo": "default"
173 }
173 }
174 ]
174 ]
175 $ hg debugupgraderepo
175 $ hg debugupgraderepo
176 (no format upgrades found in existing repository)
176 (no format upgrades found in existing repository)
177 performing an upgrade with "--run" will make the following changes:
177 performing an upgrade with "--run" will make the following changes:
178
178
179 requirements
179 requirements
180 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
180 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
181
181
182 processed revlogs:
182 processed revlogs:
183 - all-filelogs
183 - all-filelogs
184 - changelog
184 - changelog
185 - manifest
185 - manifest
186
186
187 additional optimizations are available by specifying "--optimize <name>":
187 additional optimizations are available by specifying "--optimize <name>":
188
188
189 re-delta-parent
189 re-delta-parent
190 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
190 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
191
191
192 re-delta-multibase
192 re-delta-multibase
193 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
193 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
194
194
195 re-delta-all
195 re-delta-all
196 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
196 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
197
197
198 re-delta-fulladd
198 re-delta-fulladd
199 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
199 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
200
200
201
201
202 $ hg debugupgraderepo --quiet
202 $ hg debugupgraderepo --quiet
203 requirements
203 requirements
204 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
204 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
205
205
206 processed revlogs:
206 processed revlogs:
207 - all-filelogs
207 - all-filelogs
208 - changelog
208 - changelog
209 - manifest
209 - manifest
210
210
211
211
212 --optimize can be used to add optimizations
212 --optimize can be used to add optimizations
213
213
214 $ hg debugupgrade --optimize 're-delta-parent'
214 $ hg debugupgrade --optimize 're-delta-parent'
215 (no format upgrades found in existing repository)
215 (no format upgrades found in existing repository)
216 performing an upgrade with "--run" will make the following changes:
216 performing an upgrade with "--run" will make the following changes:
217
217
218 requirements
218 requirements
219 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
219 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
220
220
221 optimisations: re-delta-parent
221 optimisations: re-delta-parent
222
222
223 re-delta-parent
223 re-delta-parent
224 deltas within internal storage will choose a new base revision if needed
224 deltas within internal storage will choose a new base revision if needed
225
225
226 processed revlogs:
226 processed revlogs:
227 - all-filelogs
227 - all-filelogs
228 - changelog
228 - changelog
229 - manifest
229 - manifest
230
230
231 additional optimizations are available by specifying "--optimize <name>":
231 additional optimizations are available by specifying "--optimize <name>":
232
232
233 re-delta-multibase
233 re-delta-multibase
234 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
234 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
235
235
236 re-delta-all
236 re-delta-all
237 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
237 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
238
238
239 re-delta-fulladd
239 re-delta-fulladd
240 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
240 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
241
241
242
242
243 modern form of the option
243 modern form of the option
244
244
245 $ hg debugupgrade --optimize re-delta-parent
245 $ hg debugupgrade --optimize re-delta-parent
246 (no format upgrades found in existing repository)
246 (no format upgrades found in existing repository)
247 performing an upgrade with "--run" will make the following changes:
247 performing an upgrade with "--run" will make the following changes:
248
248
249 requirements
249 requirements
250 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
250 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
251
251
252 optimisations: re-delta-parent
252 optimisations: re-delta-parent
253
253
254 re-delta-parent
254 re-delta-parent
255 deltas within internal storage will choose a new base revision if needed
255 deltas within internal storage will choose a new base revision if needed
256
256
257 processed revlogs:
257 processed revlogs:
258 - all-filelogs
258 - all-filelogs
259 - changelog
259 - changelog
260 - manifest
260 - manifest
261
261
262 additional optimizations are available by specifying "--optimize <name>":
262 additional optimizations are available by specifying "--optimize <name>":
263
263
264 re-delta-multibase
264 re-delta-multibase
265 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
265 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
266
266
267 re-delta-all
267 re-delta-all
268 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
268 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
269
269
270 re-delta-fulladd
270 re-delta-fulladd
271 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
271 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
272
272
273 $ hg debugupgrade --optimize re-delta-parent --quiet
273 $ hg debugupgrade --optimize re-delta-parent --quiet
274 requirements
274 requirements
275 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
275 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
276
276
277 optimisations: re-delta-parent
277 optimisations: re-delta-parent
278
278
279 processed revlogs:
279 processed revlogs:
280 - all-filelogs
280 - all-filelogs
281 - changelog
281 - changelog
282 - manifest
282 - manifest
283
283
284
284
285 unknown optimization:
285 unknown optimization:
286
286
287 $ hg debugupgrade --optimize foobar
287 $ hg debugupgrade --optimize foobar
288 abort: unknown optimization action requested: foobar
288 abort: unknown optimization action requested: foobar
289 (run without arguments to see valid optimizations)
289 (run without arguments to see valid optimizations)
290 [255]
290 [255]
291
291
292 Various sub-optimal detections work
292 Various sub-optimal detections work
293
293
294 $ cat > .hg/requires << EOF
294 $ cat > .hg/requires << EOF
295 > revlogv1
295 > revlogv1
296 > store
296 > store
297 > EOF
297 > EOF
298
298
299 $ hg debugformat
299 $ hg debugformat
300 format-variant repo
300 format-variant repo
301 fncache: no
301 fncache: no
302 dotencode: no
302 dotencode: no
303 generaldelta: no
303 generaldelta: no
304 share-safe: no
304 share-safe: no
305 sparserevlog: no
305 sparserevlog: no
306 sidedata: no
306 sidedata: no
307 persistent-nodemap: no
307 persistent-nodemap: no
308 copies-sdc: no
308 copies-sdc: no
309 plain-cl-delta: yes
309 plain-cl-delta: yes
310 compression: zlib
310 compression: zlib
311 compression-level: default
311 compression-level: default
312 $ hg debugformat --verbose
312 $ hg debugformat --verbose
313 format-variant repo config default
313 format-variant repo config default
314 fncache: no yes yes
314 fncache: no yes yes
315 dotencode: no yes yes
315 dotencode: no yes yes
316 generaldelta: no yes yes
316 generaldelta: no yes yes
317 share-safe: no no no
317 share-safe: no no no
318 sparserevlog: no yes yes
318 sparserevlog: no yes yes
319 sidedata: no no no
319 sidedata: no no no
320 persistent-nodemap: no no no
320 persistent-nodemap: no no no
321 copies-sdc: no no no
321 copies-sdc: no no no
322 plain-cl-delta: yes yes yes
322 plain-cl-delta: yes yes yes
323 compression: zlib zlib zlib
323 compression: zlib zlib zlib
324 compression-level: default default default
324 compression-level: default default default
325 $ hg debugformat --verbose --config format.usegeneraldelta=no
325 $ hg debugformat --verbose --config format.usegeneraldelta=no
326 format-variant repo config default
326 format-variant repo config default
327 fncache: no yes yes
327 fncache: no yes yes
328 dotencode: no yes yes
328 dotencode: no yes yes
329 generaldelta: no no yes
329 generaldelta: no no yes
330 share-safe: no no no
330 share-safe: no no no
331 sparserevlog: no no yes
331 sparserevlog: no no yes
332 sidedata: no no no
332 sidedata: no no no
333 persistent-nodemap: no no no
333 persistent-nodemap: no no no
334 copies-sdc: no no no
334 copies-sdc: no no no
335 plain-cl-delta: yes yes yes
335 plain-cl-delta: yes yes yes
336 compression: zlib zlib zlib
336 compression: zlib zlib zlib
337 compression-level: default default default
337 compression-level: default default default
338 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
338 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
339 format-variant repo config default
339 format-variant repo config default
340 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
340 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
341 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
341 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
342 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
342 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
343 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
343 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
344 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
344 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
345 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
345 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
346 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
346 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
347 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
347 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
348 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
348 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
349 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
349 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
350 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
350 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
351 $ hg debugupgraderepo
351 $ hg debugupgraderepo
352 repository lacks features recommended by current config options:
352 repository lacks features recommended by current config options:
353
353
354 fncache
354 fncache
355 long and reserved filenames may not work correctly; repository performance is sub-optimal
355 long and reserved filenames may not work correctly; repository performance is sub-optimal
356
356
357 dotencode
357 dotencode
358 storage of filenames beginning with a period or space may not work correctly
358 storage of filenames beginning with a period or space may not work correctly
359
359
360 generaldelta
360 generaldelta
361 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
361 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
362
362
363 sparserevlog
363 sparserevlog
364 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
364 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
365
365
366
366
367 performing an upgrade with "--run" will make the following changes:
367 performing an upgrade with "--run" will make the following changes:
368
368
369 requirements
369 requirements
370 preserved: revlogv1, store
370 preserved: revlogv1, store
371 added: dotencode, fncache, generaldelta, sparserevlog
371 added: dotencode, fncache, generaldelta, sparserevlog
372
372
373 fncache
373 fncache
374 repository will be more resilient to storing certain paths and performance of certain operations should be improved
374 repository will be more resilient to storing certain paths and performance of certain operations should be improved
375
375
376 dotencode
376 dotencode
377 repository will be better able to store files beginning with a space or period
377 repository will be better able to store files beginning with a space or period
378
378
379 generaldelta
379 generaldelta
380 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
380 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
381
381
382 sparserevlog
382 sparserevlog
383 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
383 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
384
384
385 processed revlogs:
385 processed revlogs:
386 - all-filelogs
386 - all-filelogs
387 - changelog
387 - changelog
388 - manifest
388 - manifest
389
389
390 additional optimizations are available by specifying "--optimize <name>":
390 additional optimizations are available by specifying "--optimize <name>":
391
391
392 re-delta-parent
392 re-delta-parent
393 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
393 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
394
394
395 re-delta-multibase
395 re-delta-multibase
396 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
396 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
397
397
398 re-delta-all
398 re-delta-all
399 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
399 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
400
400
401 re-delta-fulladd
401 re-delta-fulladd
402 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
402 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
403
403
404 $ hg debugupgraderepo --quiet
404 $ hg debugupgraderepo --quiet
405 requirements
405 requirements
406 preserved: revlogv1, store
406 preserved: revlogv1, store
407 added: dotencode, fncache, generaldelta, sparserevlog
407 added: dotencode, fncache, generaldelta, sparserevlog
408
408
409 processed revlogs:
409 processed revlogs:
410 - all-filelogs
410 - all-filelogs
411 - changelog
411 - changelog
412 - manifest
412 - manifest
413
413
414
414
415 $ hg --config format.dotencode=false debugupgraderepo
415 $ hg --config format.dotencode=false debugupgraderepo
416 repository lacks features recommended by current config options:
416 repository lacks features recommended by current config options:
417
417
418 fncache
418 fncache
419 long and reserved filenames may not work correctly; repository performance is sub-optimal
419 long and reserved filenames may not work correctly; repository performance is sub-optimal
420
420
421 generaldelta
421 generaldelta
422 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
422 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
423
423
424 sparserevlog
424 sparserevlog
425 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
425 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
426
426
427 repository lacks features used by the default config options:
427 repository lacks features used by the default config options:
428
428
429 dotencode
429 dotencode
430 storage of filenames beginning with a period or space may not work correctly
430 storage of filenames beginning with a period or space may not work correctly
431
431
432
432
433 performing an upgrade with "--run" will make the following changes:
433 performing an upgrade with "--run" will make the following changes:
434
434
435 requirements
435 requirements
436 preserved: revlogv1, store
436 preserved: revlogv1, store
437 added: fncache, generaldelta, sparserevlog
437 added: fncache, generaldelta, sparserevlog
438
438
439 fncache
439 fncache
440 repository will be more resilient to storing certain paths and performance of certain operations should be improved
440 repository will be more resilient to storing certain paths and performance of certain operations should be improved
441
441
442 generaldelta
442 generaldelta
443 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
443 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
444
444
445 sparserevlog
445 sparserevlog
446 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
446 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
447
447
448 processed revlogs:
448 processed revlogs:
449 - all-filelogs
449 - all-filelogs
450 - changelog
450 - changelog
451 - manifest
451 - manifest
452
452
453 additional optimizations are available by specifying "--optimize <name>":
453 additional optimizations are available by specifying "--optimize <name>":
454
454
455 re-delta-parent
455 re-delta-parent
456 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
456 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
457
457
458 re-delta-multibase
458 re-delta-multibase
459 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
459 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
460
460
461 re-delta-all
461 re-delta-all
462 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
462 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
463
463
464 re-delta-fulladd
464 re-delta-fulladd
465 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
465 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
466
466
467
467
468 $ cd ..
468 $ cd ..
469
469
470 Upgrading a repository that is already modern essentially no-ops
470 Upgrading a repository that is already modern essentially no-ops
471
471
472 $ hg init modern
472 $ hg init modern
473 $ hg -R modern debugupgraderepo --run
473 $ hg -R modern debugupgraderepo --run
474 nothing to do
474 nothing to do
475
475
476 Upgrading a repository to generaldelta works
476 Upgrading a repository to generaldelta works
477
477
478 $ hg --config format.usegeneraldelta=false init upgradegd
478 $ hg --config format.usegeneraldelta=false init upgradegd
479 $ cd upgradegd
479 $ cd upgradegd
480 $ touch f0
480 $ touch f0
481 $ hg -q commit -A -m initial
481 $ hg -q commit -A -m initial
482 $ mkdir FooBarDirectory.d
482 $ mkdir FooBarDirectory.d
483 $ touch FooBarDirectory.d/f1
483 $ touch FooBarDirectory.d/f1
484 $ hg -q commit -A -m 'add f1'
484 $ hg -q commit -A -m 'add f1'
485 $ hg -q up -r 0
485 $ hg -q up -r 0
486 >>> from __future__ import absolute_import, print_function
486 >>> from __future__ import absolute_import, print_function
487 >>> import random
487 >>> import random
488 >>> random.seed(0) # have a reproducible content
488 >>> random.seed(0) # have a reproducible content
489 >>> with open("f2", "wb") as f:
489 >>> with open("f2", "wb") as f:
490 ... for i in range(100000):
490 ... for i in range(100000):
491 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
491 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
492 $ hg -q commit -A -m 'add f2'
492 $ hg -q commit -A -m 'add f2'
493
493
494 make sure we have a .d file
494 make sure we have a .d file
495
495
496 $ ls -d .hg/store/data/*
496 $ ls -d .hg/store/data/*
497 .hg/store/data/_foo_bar_directory.d.hg
497 .hg/store/data/_foo_bar_directory.d.hg
498 .hg/store/data/f0.i
498 .hg/store/data/f0.i
499 .hg/store/data/f2.d
499 .hg/store/data/f2.d
500 .hg/store/data/f2.i
500 .hg/store/data/f2.i
501
501
502 $ hg debugupgraderepo --run --config format.sparse-revlog=false
502 $ hg debugupgraderepo --run --config format.sparse-revlog=false
503 upgrade will perform the following actions:
503 upgrade will perform the following actions:
504
504
505 requirements
505 requirements
506 preserved: dotencode, fncache, revlogv1, store
506 preserved: dotencode, fncache, revlogv1, store
507 added: generaldelta
507 added: generaldelta
508
508
509 generaldelta
509 generaldelta
510 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
510 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
511
511
512 processed revlogs:
512 processed revlogs:
513 - all-filelogs
513 - all-filelogs
514 - changelog
514 - changelog
515 - manifest
515 - manifest
516
516
517 beginning upgrade...
517 beginning upgrade...
518 repository locked and read-only
518 repository locked and read-only
519 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
519 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
520 (it is safe to interrupt this process any time before data migration completes)
520 (it is safe to interrupt this process any time before data migration completes)
521 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
521 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
522 migrating 519 KB in store; 1.05 MB tracked data
522 migrating 519 KB in store; 1.05 MB tracked data
523 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
523 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
524 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
524 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
525 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
525 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
526 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
526 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
527 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
527 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
528 finished migrating 3 changelog revisions; change in size: 0 bytes
528 finished migrating 3 changelog revisions; change in size: 0 bytes
529 finished migrating 9 total revisions; total change in store size: -17 bytes
529 finished migrating 9 total revisions; total change in store size: -17 bytes
530 copying phaseroots
530 copying phaseroots
531 data fully upgraded in a temporary repository
531 data fully upgraded in a temporary repository
532 marking source repository as being upgraded; clients will be unable to read from repository
532 marking source repository as being upgraded; clients will be unable to read from repository
533 starting in-place swap of repository data
533 starting in-place swap of repository data
534 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
534 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
535 replacing store...
535 replacing store...
536 store replacement complete; repository was inconsistent for *s (glob)
536 store replacement complete; repository was inconsistent for *s (glob)
537 finalizing requirements file and making repository readable again
537 finalizing requirements file and making repository readable again
538 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
538 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
539 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
539 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
540 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
540 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
541
541
542 Original requirements backed up
542 Original requirements backed up
543
543
544 $ cat .hg/upgradebackup.*/requires
544 $ cat .hg/upgradebackup.*/requires
545 dotencode
545 dotencode
546 fncache
546 fncache
547 revlogv1
547 revlogv1
548 store
548 store
549
549
550 generaldelta added to original requirements files
550 generaldelta added to original requirements files
551
551
552 $ cat .hg/requires
552 $ cat .hg/requires
553 dotencode
553 dotencode
554 fncache
554 fncache
555 generaldelta
555 generaldelta
556 revlogv1
556 revlogv1
557 store
557 store
558
558
559 store directory has files we expect
559 store directory has files we expect
560
560
561 $ ls .hg/store
561 $ ls .hg/store
562 00changelog.i
562 00changelog.i
563 00manifest.i
563 00manifest.i
564 data
564 data
565 fncache
565 fncache
566 phaseroots
566 phaseroots
567 undo
567 undo
568 undo.backupfiles
568 undo.backupfiles
569 undo.phaseroots
569 undo.phaseroots
570
570
571 manifest should be generaldelta
571 manifest should be generaldelta
572
572
573 $ hg debugrevlog -m | grep flags
573 $ hg debugrevlog -m | grep flags
574 flags : inline, generaldelta
574 flags : inline, generaldelta
575
575
576 verify should be happy
576 verify should be happy
577
577
578 $ hg verify
578 $ hg verify
579 checking changesets
579 checking changesets
580 checking manifests
580 checking manifests
581 crosschecking files in changesets and manifests
581 crosschecking files in changesets and manifests
582 checking files
582 checking files
583 checked 3 changesets with 3 changes to 3 files
583 checked 3 changesets with 3 changes to 3 files
584
584
585 old store should be backed up
585 old store should be backed up
586
586
587 $ ls -d .hg/upgradebackup.*/
587 $ ls -d .hg/upgradebackup.*/
588 .hg/upgradebackup.*/ (glob)
588 .hg/upgradebackup.*/ (glob)
589 $ ls .hg/upgradebackup.*/store
589 $ ls .hg/upgradebackup.*/store
590 00changelog.i
590 00changelog.i
591 00manifest.i
591 00manifest.i
592 data
592 data
593 fncache
593 fncache
594 phaseroots
594 phaseroots
595 undo
595 undo
596 undo.backup.fncache
596 undo.backup.fncache
597 undo.backupfiles
597 undo.backupfiles
598 undo.phaseroots
598 undo.phaseroots
599
599
600 unless --no-backup is passed
600 unless --no-backup is passed
601
601
602 $ rm -rf .hg/upgradebackup.*/
602 $ rm -rf .hg/upgradebackup.*/
603 $ hg debugupgraderepo --run --no-backup
603 $ hg debugupgraderepo --run --no-backup
604 upgrade will perform the following actions:
604 upgrade will perform the following actions:
605
605
606 requirements
606 requirements
607 preserved: dotencode, fncache, generaldelta, revlogv1, store
607 preserved: dotencode, fncache, generaldelta, revlogv1, store
608 added: sparserevlog
608 added: sparserevlog
609
609
610 sparserevlog
610 sparserevlog
611 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
611 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
612
612
613 processed revlogs:
613 processed revlogs:
614 - all-filelogs
614 - all-filelogs
615 - changelog
615 - changelog
616 - manifest
616 - manifest
617
617
618 beginning upgrade...
618 beginning upgrade...
619 repository locked and read-only
619 repository locked and read-only
620 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
620 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
621 (it is safe to interrupt this process any time before data migration completes)
621 (it is safe to interrupt this process any time before data migration completes)
622 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
622 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
623 migrating 519 KB in store; 1.05 MB tracked data
623 migrating 519 KB in store; 1.05 MB tracked data
624 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
624 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
625 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
625 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
626 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
626 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
627 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
627 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
628 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
628 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
629 finished migrating 3 changelog revisions; change in size: 0 bytes
629 finished migrating 3 changelog revisions; change in size: 0 bytes
630 finished migrating 9 total revisions; total change in store size: 0 bytes
630 finished migrating 9 total revisions; total change in store size: 0 bytes
631 copying phaseroots
631 copying phaseroots
632 data fully upgraded in a temporary repository
632 data fully upgraded in a temporary repository
633 marking source repository as being upgraded; clients will be unable to read from repository
633 marking source repository as being upgraded; clients will be unable to read from repository
634 starting in-place swap of repository data
634 starting in-place swap of repository data
635 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
636 replacing store...
635 replacing store...
637 store replacement complete; repository was inconsistent for * (glob)
636 store replacement complete; repository was inconsistent for * (glob)
638 finalizing requirements file and making repository readable again
637 finalizing requirements file and making repository readable again
639 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
640 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
638 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
641 $ ls -1 .hg/ | grep upgradebackup
639 $ ls -1 .hg/ | grep upgradebackup
642 [1]
640 [1]
643
641
644 We can restrict optimization to some revlog:
642 We can restrict optimization to some revlog:
645
643
646 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
644 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
647 upgrade will perform the following actions:
645 upgrade will perform the following actions:
648
646
649 requirements
647 requirements
650 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
648 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
651
649
652 optimisations: re-delta-parent
650 optimisations: re-delta-parent
653
651
654 re-delta-parent
652 re-delta-parent
655 deltas within internal storage will choose a new base revision if needed
653 deltas within internal storage will choose a new base revision if needed
656
654
657 processed revlogs:
655 processed revlogs:
658 - manifest
656 - manifest
659
657
660 beginning upgrade...
658 beginning upgrade...
661 repository locked and read-only
659 repository locked and read-only
662 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
660 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
663 (it is safe to interrupt this process any time before data migration completes)
661 (it is safe to interrupt this process any time before data migration completes)
664 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
662 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
665 migrating 519 KB in store; 1.05 MB tracked data
663 migrating 519 KB in store; 1.05 MB tracked data
666 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
664 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
667 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
665 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
668 blindly copying data/f0.i containing 1 revisions
666 blindly copying data/f0.i containing 1 revisions
669 blindly copying data/f2.i containing 1 revisions
667 blindly copying data/f2.i containing 1 revisions
670 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
668 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
671 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
669 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
672 cloning 3 revisions from 00manifest.i
670 cloning 3 revisions from 00manifest.i
673 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
671 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
674 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
672 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
675 blindly copying 00changelog.i containing 3 revisions
673 blindly copying 00changelog.i containing 3 revisions
676 finished migrating 3 changelog revisions; change in size: 0 bytes
674 finished migrating 3 changelog revisions; change in size: 0 bytes
677 finished migrating 9 total revisions; total change in store size: 0 bytes
675 finished migrating 9 total revisions; total change in store size: 0 bytes
678 copying phaseroots
676 copying phaseroots
679 data fully upgraded in a temporary repository
677 data fully upgraded in a temporary repository
680 marking source repository as being upgraded; clients will be unable to read from repository
678 marking source repository as being upgraded; clients will be unable to read from repository
681 starting in-place swap of repository data
679 starting in-place swap of repository data
682 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
683 replacing store...
680 replacing store...
684 store replacement complete; repository was inconsistent for *s (glob)
681 store replacement complete; repository was inconsistent for *s (glob)
685 finalizing requirements file and making repository readable again
682 finalizing requirements file and making repository readable again
686 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
687 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
683 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
688
684
689 Check that the repo still works fine
685 Check that the repo still works fine
690
686
691 $ hg log -G --stat
687 $ hg log -G --stat
692 @ changeset: 2:76d4395f5413 (no-py3 !)
688 @ changeset: 2:76d4395f5413 (no-py3 !)
693 @ changeset: 2:fca376863211 (py3 !)
689 @ changeset: 2:fca376863211 (py3 !)
694 | tag: tip
690 | tag: tip
695 | parent: 0:ba592bf28da2
691 | parent: 0:ba592bf28da2
696 | user: test
692 | user: test
697 | date: Thu Jan 01 00:00:00 1970 +0000
693 | date: Thu Jan 01 00:00:00 1970 +0000
698 | summary: add f2
694 | summary: add f2
699 |
695 |
700 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
696 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
701 | 1 files changed, 100000 insertions(+), 0 deletions(-)
697 | 1 files changed, 100000 insertions(+), 0 deletions(-)
702 |
698 |
703 | o changeset: 1:2029ce2354e2
699 | o changeset: 1:2029ce2354e2
704 |/ user: test
700 |/ user: test
705 | date: Thu Jan 01 00:00:00 1970 +0000
701 | date: Thu Jan 01 00:00:00 1970 +0000
706 | summary: add f1
702 | summary: add f1
707 |
703 |
708 |
704 |
709 o changeset: 0:ba592bf28da2
705 o changeset: 0:ba592bf28da2
710 user: test
706 user: test
711 date: Thu Jan 01 00:00:00 1970 +0000
707 date: Thu Jan 01 00:00:00 1970 +0000
712 summary: initial
708 summary: initial
713
709
714
710
715
711
716 $ hg verify
712 $ hg verify
717 checking changesets
713 checking changesets
718 checking manifests
714 checking manifests
719 crosschecking files in changesets and manifests
715 crosschecking files in changesets and manifests
720 checking files
716 checking files
721 checked 3 changesets with 3 changes to 3 files
717 checked 3 changesets with 3 changes to 3 files
722
718
723 Check we can select negatively
719 Check we can select negatively
724
720
725 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
721 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
726 upgrade will perform the following actions:
722 upgrade will perform the following actions:
727
723
728 requirements
724 requirements
729 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
725 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
730
726
731 optimisations: re-delta-parent
727 optimisations: re-delta-parent
732
728
733 re-delta-parent
729 re-delta-parent
734 deltas within internal storage will choose a new base revision if needed
730 deltas within internal storage will choose a new base revision if needed
735
731
736 processed revlogs:
732 processed revlogs:
737 - all-filelogs
733 - all-filelogs
738 - changelog
734 - changelog
739
735
740 beginning upgrade...
736 beginning upgrade...
741 repository locked and read-only
737 repository locked and read-only
742 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
738 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
743 (it is safe to interrupt this process any time before data migration completes)
739 (it is safe to interrupt this process any time before data migration completes)
744 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
740 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
745 migrating 519 KB in store; 1.05 MB tracked data
741 migrating 519 KB in store; 1.05 MB tracked data
746 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
742 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
747 cloning 1 revisions from data/FooBarDirectory.d/f1.i
743 cloning 1 revisions from data/FooBarDirectory.d/f1.i
748 cloning 1 revisions from data/f0.i
744 cloning 1 revisions from data/f0.i
749 cloning 1 revisions from data/f2.i
745 cloning 1 revisions from data/f2.i
750 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
746 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
751 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
747 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
752 blindly copying 00manifest.i containing 3 revisions
748 blindly copying 00manifest.i containing 3 revisions
753 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
749 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
754 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
750 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
755 cloning 3 revisions from 00changelog.i
751 cloning 3 revisions from 00changelog.i
756 finished migrating 3 changelog revisions; change in size: 0 bytes
752 finished migrating 3 changelog revisions; change in size: 0 bytes
757 finished migrating 9 total revisions; total change in store size: 0 bytes
753 finished migrating 9 total revisions; total change in store size: 0 bytes
758 copying phaseroots
754 copying phaseroots
759 data fully upgraded in a temporary repository
755 data fully upgraded in a temporary repository
760 marking source repository as being upgraded; clients will be unable to read from repository
756 marking source repository as being upgraded; clients will be unable to read from repository
761 starting in-place swap of repository data
757 starting in-place swap of repository data
762 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
763 replacing store...
758 replacing store...
764 store replacement complete; repository was inconsistent for *s (glob)
759 store replacement complete; repository was inconsistent for *s (glob)
765 finalizing requirements file and making repository readable again
760 finalizing requirements file and making repository readable again
766 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
767 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
761 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
768 $ hg verify
762 $ hg verify
769 checking changesets
763 checking changesets
770 checking manifests
764 checking manifests
771 crosschecking files in changesets and manifests
765 crosschecking files in changesets and manifests
772 checking files
766 checking files
773 checked 3 changesets with 3 changes to 3 files
767 checked 3 changesets with 3 changes to 3 files
774
768
775 Check that we can select changelog only
769 Check that we can select changelog only
776
770
777 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
771 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
778 upgrade will perform the following actions:
772 upgrade will perform the following actions:
779
773
780 requirements
774 requirements
781 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
775 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
782
776
783 optimisations: re-delta-parent
777 optimisations: re-delta-parent
784
778
785 re-delta-parent
779 re-delta-parent
786 deltas within internal storage will choose a new base revision if needed
780 deltas within internal storage will choose a new base revision if needed
787
781
788 processed revlogs:
782 processed revlogs:
789 - changelog
783 - changelog
790
784
791 beginning upgrade...
785 beginning upgrade...
792 repository locked and read-only
786 repository locked and read-only
793 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
787 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
794 (it is safe to interrupt this process any time before data migration completes)
788 (it is safe to interrupt this process any time before data migration completes)
795 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
789 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
796 migrating 519 KB in store; 1.05 MB tracked data
790 migrating 519 KB in store; 1.05 MB tracked data
797 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
791 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
798 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
792 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
799 blindly copying data/f0.i containing 1 revisions
793 blindly copying data/f0.i containing 1 revisions
800 blindly copying data/f2.i containing 1 revisions
794 blindly copying data/f2.i containing 1 revisions
801 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
795 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
802 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
796 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
803 blindly copying 00manifest.i containing 3 revisions
797 blindly copying 00manifest.i containing 3 revisions
804 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
798 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
805 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
799 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
806 cloning 3 revisions from 00changelog.i
800 cloning 3 revisions from 00changelog.i
807 finished migrating 3 changelog revisions; change in size: 0 bytes
801 finished migrating 3 changelog revisions; change in size: 0 bytes
808 finished migrating 9 total revisions; total change in store size: 0 bytes
802 finished migrating 9 total revisions; total change in store size: 0 bytes
809 copying phaseroots
803 copying phaseroots
810 data fully upgraded in a temporary repository
804 data fully upgraded in a temporary repository
811 marking source repository as being upgraded; clients will be unable to read from repository
805 marking source repository as being upgraded; clients will be unable to read from repository
812 starting in-place swap of repository data
806 starting in-place swap of repository data
813 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
814 replacing store...
807 replacing store...
815 store replacement complete; repository was inconsistent for *s (glob)
808 store replacement complete; repository was inconsistent for *s (glob)
816 finalizing requirements file and making repository readable again
809 finalizing requirements file and making repository readable again
817 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
818 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
810 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
819 $ hg verify
811 $ hg verify
820 checking changesets
812 checking changesets
821 checking manifests
813 checking manifests
822 crosschecking files in changesets and manifests
814 crosschecking files in changesets and manifests
823 checking files
815 checking files
824 checked 3 changesets with 3 changes to 3 files
816 checked 3 changesets with 3 changes to 3 files
825
817
826 Check that we can select filelog only
818 Check that we can select filelog only
827
819
828 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
820 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
829 upgrade will perform the following actions:
821 upgrade will perform the following actions:
830
822
831 requirements
823 requirements
832 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
824 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
833
825
834 optimisations: re-delta-parent
826 optimisations: re-delta-parent
835
827
836 re-delta-parent
828 re-delta-parent
837 deltas within internal storage will choose a new base revision if needed
829 deltas within internal storage will choose a new base revision if needed
838
830
839 processed revlogs:
831 processed revlogs:
840 - all-filelogs
832 - all-filelogs
841
833
842 beginning upgrade...
834 beginning upgrade...
843 repository locked and read-only
835 repository locked and read-only
844 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
836 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
845 (it is safe to interrupt this process any time before data migration completes)
837 (it is safe to interrupt this process any time before data migration completes)
846 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
838 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
847 migrating 519 KB in store; 1.05 MB tracked data
839 migrating 519 KB in store; 1.05 MB tracked data
848 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
840 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
849 cloning 1 revisions from data/FooBarDirectory.d/f1.i
841 cloning 1 revisions from data/FooBarDirectory.d/f1.i
850 cloning 1 revisions from data/f0.i
842 cloning 1 revisions from data/f0.i
851 cloning 1 revisions from data/f2.i
843 cloning 1 revisions from data/f2.i
852 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
844 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
853 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
845 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
854 blindly copying 00manifest.i containing 3 revisions
846 blindly copying 00manifest.i containing 3 revisions
855 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
847 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
856 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
848 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
857 blindly copying 00changelog.i containing 3 revisions
849 blindly copying 00changelog.i containing 3 revisions
858 finished migrating 3 changelog revisions; change in size: 0 bytes
850 finished migrating 3 changelog revisions; change in size: 0 bytes
859 finished migrating 9 total revisions; total change in store size: 0 bytes
851 finished migrating 9 total revisions; total change in store size: 0 bytes
860 copying phaseroots
852 copying phaseroots
861 data fully upgraded in a temporary repository
853 data fully upgraded in a temporary repository
862 marking source repository as being upgraded; clients will be unable to read from repository
854 marking source repository as being upgraded; clients will be unable to read from repository
863 starting in-place swap of repository data
855 starting in-place swap of repository data
864 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
865 replacing store...
856 replacing store...
866 store replacement complete; repository was inconsistent for *s (glob)
857 store replacement complete; repository was inconsistent for *s (glob)
867 finalizing requirements file and making repository readable again
858 finalizing requirements file and making repository readable again
868 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
869 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
859 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
870 $ hg verify
860 $ hg verify
871 checking changesets
861 checking changesets
872 checking manifests
862 checking manifests
873 crosschecking files in changesets and manifests
863 crosschecking files in changesets and manifests
874 checking files
864 checking files
875 checked 3 changesets with 3 changes to 3 files
865 checked 3 changesets with 3 changes to 3 files
876
866
877
867
878 Check you can't skip revlog clone during important format downgrade
868 Check you can't skip revlog clone during important format downgrade
879
869
880 $ echo "[format]" > .hg/hgrc
870 $ echo "[format]" > .hg/hgrc
881 $ echo "sparse-revlog=no" >> .hg/hgrc
871 $ echo "sparse-revlog=no" >> .hg/hgrc
882 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
872 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
883 ignoring revlogs selection flags, format requirements change: sparserevlog
873 ignoring revlogs selection flags, format requirements change: sparserevlog
884 upgrade will perform the following actions:
874 upgrade will perform the following actions:
885
875
886 requirements
876 requirements
887 preserved: dotencode, fncache, generaldelta, revlogv1, store
877 preserved: dotencode, fncache, generaldelta, revlogv1, store
888 removed: sparserevlog
878 removed: sparserevlog
889
879
890 optimisations: re-delta-parent
880 optimisations: re-delta-parent
891
881
892 re-delta-parent
882 re-delta-parent
893 deltas within internal storage will choose a new base revision if needed
883 deltas within internal storage will choose a new base revision if needed
894
884
895 processed revlogs:
885 processed revlogs:
896 - all-filelogs
886 - all-filelogs
897 - changelog
887 - changelog
898 - manifest
888 - manifest
899
889
900 beginning upgrade...
890 beginning upgrade...
901 repository locked and read-only
891 repository locked and read-only
902 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
892 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
903 (it is safe to interrupt this process any time before data migration completes)
893 (it is safe to interrupt this process any time before data migration completes)
904 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
894 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
905 migrating 519 KB in store; 1.05 MB tracked data
895 migrating 519 KB in store; 1.05 MB tracked data
906 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
896 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
907 cloning 1 revisions from data/FooBarDirectory.d/f1.i
897 cloning 1 revisions from data/FooBarDirectory.d/f1.i
908 cloning 1 revisions from data/f0.i
898 cloning 1 revisions from data/f0.i
909 cloning 1 revisions from data/f2.i
899 cloning 1 revisions from data/f2.i
910 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
900 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
911 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
901 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
912 cloning 3 revisions from 00manifest.i
902 cloning 3 revisions from 00manifest.i
913 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
903 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
914 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
904 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
915 cloning 3 revisions from 00changelog.i
905 cloning 3 revisions from 00changelog.i
916 finished migrating 3 changelog revisions; change in size: 0 bytes
906 finished migrating 3 changelog revisions; change in size: 0 bytes
917 finished migrating 9 total revisions; total change in store size: 0 bytes
907 finished migrating 9 total revisions; total change in store size: 0 bytes
918 copying phaseroots
908 copying phaseroots
919 data fully upgraded in a temporary repository
909 data fully upgraded in a temporary repository
920 marking source repository as being upgraded; clients will be unable to read from repository
910 marking source repository as being upgraded; clients will be unable to read from repository
921 starting in-place swap of repository data
911 starting in-place swap of repository data
922 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
923 replacing store...
912 replacing store...
924 store replacement complete; repository was inconsistent for *s (glob)
913 store replacement complete; repository was inconsistent for *s (glob)
925 finalizing requirements file and making repository readable again
914 finalizing requirements file and making repository readable again
926 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
927 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
915 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
928 $ hg verify
916 $ hg verify
929 checking changesets
917 checking changesets
930 checking manifests
918 checking manifests
931 crosschecking files in changesets and manifests
919 crosschecking files in changesets and manifests
932 checking files
920 checking files
933 checked 3 changesets with 3 changes to 3 files
921 checked 3 changesets with 3 changes to 3 files
934
922
935 Check you can't skip revlog clone during important format upgrade
923 Check you can't skip revlog clone during important format upgrade
936
924
937 $ echo "sparse-revlog=yes" >> .hg/hgrc
925 $ echo "sparse-revlog=yes" >> .hg/hgrc
938 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
926 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
939 ignoring revlogs selection flags, format requirements change: sparserevlog
927 ignoring revlogs selection flags, format requirements change: sparserevlog
940 upgrade will perform the following actions:
928 upgrade will perform the following actions:
941
929
942 requirements
930 requirements
943 preserved: dotencode, fncache, generaldelta, revlogv1, store
931 preserved: dotencode, fncache, generaldelta, revlogv1, store
944 added: sparserevlog
932 added: sparserevlog
945
933
946 optimisations: re-delta-parent
934 optimisations: re-delta-parent
947
935
948 sparserevlog
936 sparserevlog
949 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
937 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
950
938
951 re-delta-parent
939 re-delta-parent
952 deltas within internal storage will choose a new base revision if needed
940 deltas within internal storage will choose a new base revision if needed
953
941
954 processed revlogs:
942 processed revlogs:
955 - all-filelogs
943 - all-filelogs
956 - changelog
944 - changelog
957 - manifest
945 - manifest
958
946
959 beginning upgrade...
947 beginning upgrade...
960 repository locked and read-only
948 repository locked and read-only
961 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
949 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
962 (it is safe to interrupt this process any time before data migration completes)
950 (it is safe to interrupt this process any time before data migration completes)
963 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
951 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
964 migrating 519 KB in store; 1.05 MB tracked data
952 migrating 519 KB in store; 1.05 MB tracked data
965 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
953 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
966 cloning 1 revisions from data/FooBarDirectory.d/f1.i
954 cloning 1 revisions from data/FooBarDirectory.d/f1.i
967 cloning 1 revisions from data/f0.i
955 cloning 1 revisions from data/f0.i
968 cloning 1 revisions from data/f2.i
956 cloning 1 revisions from data/f2.i
969 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
957 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
970 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
958 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
971 cloning 3 revisions from 00manifest.i
959 cloning 3 revisions from 00manifest.i
972 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
960 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
973 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
961 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
974 cloning 3 revisions from 00changelog.i
962 cloning 3 revisions from 00changelog.i
975 finished migrating 3 changelog revisions; change in size: 0 bytes
963 finished migrating 3 changelog revisions; change in size: 0 bytes
976 finished migrating 9 total revisions; total change in store size: 0 bytes
964 finished migrating 9 total revisions; total change in store size: 0 bytes
977 copying phaseroots
965 copying phaseroots
978 data fully upgraded in a temporary repository
966 data fully upgraded in a temporary repository
979 marking source repository as being upgraded; clients will be unable to read from repository
967 marking source repository as being upgraded; clients will be unable to read from repository
980 starting in-place swap of repository data
968 starting in-place swap of repository data
981 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
982 replacing store...
969 replacing store...
983 store replacement complete; repository was inconsistent for *s (glob)
970 store replacement complete; repository was inconsistent for *s (glob)
984 finalizing requirements file and making repository readable again
971 finalizing requirements file and making repository readable again
985 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
986 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
972 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
987 $ hg verify
973 $ hg verify
988 checking changesets
974 checking changesets
989 checking manifests
975 checking manifests
990 crosschecking files in changesets and manifests
976 crosschecking files in changesets and manifests
991 checking files
977 checking files
992 checked 3 changesets with 3 changes to 3 files
978 checked 3 changesets with 3 changes to 3 files
993
979
994 $ cd ..
980 $ cd ..
995
981
996 store files with special filenames aren't encoded during copy
982 store files with special filenames aren't encoded during copy
997
983
998 $ hg init store-filenames
984 $ hg init store-filenames
999 $ cd store-filenames
985 $ cd store-filenames
1000 $ touch foo
986 $ touch foo
1001 $ hg -q commit -A -m initial
987 $ hg -q commit -A -m initial
1002 $ touch .hg/store/.XX_special_filename
988 $ touch .hg/store/.XX_special_filename
1003
989
1004 $ hg debugupgraderepo --run
990 $ hg debugupgraderepo --run
1005 nothing to do
991 nothing to do
1006 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
992 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
1007 upgrade will perform the following actions:
993 upgrade will perform the following actions:
1008
994
1009 requirements
995 requirements
1010 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
996 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1011
997
1012 optimisations: re-delta-fulladd
998 optimisations: re-delta-fulladd
1013
999
1014 re-delta-fulladd
1000 re-delta-fulladd
1015 each revision will be added as new content to the internal storage; this will likely drastically slow down execution time, but some extensions might need it
1001 each revision will be added as new content to the internal storage; this will likely drastically slow down execution time, but some extensions might need it
1016
1002
1017 processed revlogs:
1003 processed revlogs:
1018 - all-filelogs
1004 - all-filelogs
1019 - changelog
1005 - changelog
1020 - manifest
1006 - manifest
1021
1007
1022 beginning upgrade...
1008 beginning upgrade...
1023 repository locked and read-only
1009 repository locked and read-only
1024 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1010 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1025 (it is safe to interrupt this process any time before data migration completes)
1011 (it is safe to interrupt this process any time before data migration completes)
1026 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1012 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1027 migrating 301 bytes in store; 107 bytes tracked data
1013 migrating 301 bytes in store; 107 bytes tracked data
1028 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1014 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1029 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1015 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1030 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1016 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1031 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1017 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1032 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1018 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1033 finished migrating 1 changelog revisions; change in size: 0 bytes
1019 finished migrating 1 changelog revisions; change in size: 0 bytes
1034 finished migrating 3 total revisions; total change in store size: 0 bytes
1020 finished migrating 3 total revisions; total change in store size: 0 bytes
1035 copying .XX_special_filename
1021 copying .XX_special_filename
1036 copying phaseroots
1022 copying phaseroots
1037 data fully upgraded in a temporary repository
1023 data fully upgraded in a temporary repository
1038 marking source repository as being upgraded; clients will be unable to read from repository
1024 marking source repository as being upgraded; clients will be unable to read from repository
1039 starting in-place swap of repository data
1025 starting in-place swap of repository data
1040 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1026 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1041 replacing store...
1027 replacing store...
1042 store replacement complete; repository was inconsistent for *s (glob)
1028 store replacement complete; repository was inconsistent for *s (glob)
1043 finalizing requirements file and making repository readable again
1029 finalizing requirements file and making repository readable again
1044 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1030 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1045 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1031 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1046 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1032 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1047
1033
1048 fncache is valid after upgrade
1034 fncache is valid after upgrade
1049
1035
1050 $ hg debugrebuildfncache
1036 $ hg debugrebuildfncache
1051 fncache already up to date
1037 fncache already up to date
1052
1038
1053 $ cd ..
1039 $ cd ..
1054
1040
1055 Check upgrading a large file repository
1041 Check upgrading a large file repository
1056 ---------------------------------------
1042 ---------------------------------------
1057
1043
1058 $ hg init largefilesrepo
1044 $ hg init largefilesrepo
1059 $ cat << EOF >> largefilesrepo/.hg/hgrc
1045 $ cat << EOF >> largefilesrepo/.hg/hgrc
1060 > [extensions]
1046 > [extensions]
1061 > largefiles =
1047 > largefiles =
1062 > EOF
1048 > EOF
1063
1049
1064 $ cd largefilesrepo
1050 $ cd largefilesrepo
1065 $ touch foo
1051 $ touch foo
1066 $ hg add --large foo
1052 $ hg add --large foo
1067 $ hg -q commit -m initial
1053 $ hg -q commit -m initial
1068 $ cat .hg/requires
1054 $ cat .hg/requires
1069 dotencode
1055 dotencode
1070 fncache
1056 fncache
1071 generaldelta
1057 generaldelta
1072 largefiles
1058 largefiles
1073 revlogv1
1059 revlogv1
1074 sparserevlog
1060 sparserevlog
1075 store
1061 store
1076
1062
1077 $ hg debugupgraderepo --run
1063 $ hg debugupgraderepo --run
1078 nothing to do
1064 nothing to do
1079 $ cat .hg/requires
1065 $ cat .hg/requires
1080 dotencode
1066 dotencode
1081 fncache
1067 fncache
1082 generaldelta
1068 generaldelta
1083 largefiles
1069 largefiles
1084 revlogv1
1070 revlogv1
1085 sparserevlog
1071 sparserevlog
1086 store
1072 store
1087
1073
1088 $ cat << EOF >> .hg/hgrc
1074 $ cat << EOF >> .hg/hgrc
1089 > [extensions]
1075 > [extensions]
1090 > lfs =
1076 > lfs =
1091 > [lfs]
1077 > [lfs]
1092 > threshold = 10
1078 > threshold = 10
1093 > EOF
1079 > EOF
1094 $ echo '123456789012345' > lfs.bin
1080 $ echo '123456789012345' > lfs.bin
1095 $ hg ci -Am 'lfs.bin'
1081 $ hg ci -Am 'lfs.bin'
1096 adding lfs.bin
1082 adding lfs.bin
1097 $ grep lfs .hg/requires
1083 $ grep lfs .hg/requires
1098 lfs
1084 lfs
1099 $ find .hg/store/lfs -type f
1085 $ find .hg/store/lfs -type f
1100 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1086 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1101
1087
1102 $ hg debugupgraderepo --run
1088 $ hg debugupgraderepo --run
1103 nothing to do
1089 nothing to do
1104
1090
1105 $ grep lfs .hg/requires
1091 $ grep lfs .hg/requires
1106 lfs
1092 lfs
1107 $ find .hg/store/lfs -type f
1093 $ find .hg/store/lfs -type f
1108 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1094 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1109 $ hg verify
1095 $ hg verify
1110 checking changesets
1096 checking changesets
1111 checking manifests
1097 checking manifests
1112 crosschecking files in changesets and manifests
1098 crosschecking files in changesets and manifests
1113 checking files
1099 checking files
1114 checked 2 changesets with 2 changes to 2 files
1100 checked 2 changesets with 2 changes to 2 files
1115 $ hg debugdata lfs.bin 0
1101 $ hg debugdata lfs.bin 0
1116 version https://git-lfs.github.com/spec/v1
1102 version https://git-lfs.github.com/spec/v1
1117 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1103 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1118 size 16
1104 size 16
1119 x-is-binary 0
1105 x-is-binary 0
1120
1106
1121 $ cd ..
1107 $ cd ..
1122
1108
1123 repository config is taken in account
1109 repository config is taken in account
1124 -------------------------------------
1110 -------------------------------------
1125
1111
1126 $ cat << EOF >> $HGRCPATH
1112 $ cat << EOF >> $HGRCPATH
1127 > [format]
1113 > [format]
1128 > maxchainlen = 1
1114 > maxchainlen = 1
1129 > EOF
1115 > EOF
1130
1116
1131 $ hg init localconfig
1117 $ hg init localconfig
1132 $ cd localconfig
1118 $ cd localconfig
1133 $ cat << EOF > file
1119 $ cat << EOF > file
1134 > some content
1120 > some content
1135 > with some length
1121 > with some length
1136 > to make sure we get a delta
1122 > to make sure we get a delta
1137 > after changes
1123 > after changes
1138 > very long
1124 > very long
1139 > very long
1125 > very long
1140 > very long
1126 > very long
1141 > very long
1127 > very long
1142 > very long
1128 > very long
1143 > very long
1129 > very long
1144 > very long
1130 > very long
1145 > very long
1131 > very long
1146 > very long
1132 > very long
1147 > very long
1133 > very long
1148 > very long
1134 > very long
1149 > EOF
1135 > EOF
1150 $ hg -q commit -A -m A
1136 $ hg -q commit -A -m A
1151 $ echo "new line" >> file
1137 $ echo "new line" >> file
1152 $ hg -q commit -m B
1138 $ hg -q commit -m B
1153 $ echo "new line" >> file
1139 $ echo "new line" >> file
1154 $ hg -q commit -m C
1140 $ hg -q commit -m C
1155
1141
1156 $ cat << EOF >> .hg/hgrc
1142 $ cat << EOF >> .hg/hgrc
1157 > [format]
1143 > [format]
1158 > maxchainlen = 9001
1144 > maxchainlen = 9001
1159 > EOF
1145 > EOF
1160 $ hg config format
1146 $ hg config format
1161 format.maxchainlen=9001
1147 format.maxchainlen=9001
1162 $ hg debugdeltachain file
1148 $ hg debugdeltachain file
1163 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1149 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1164 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1150 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1165 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1151 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1166 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1152 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1167
1153
1168 $ hg debugupgraderepo --run --optimize 're-delta-all'
1154 $ hg debugupgraderepo --run --optimize 're-delta-all'
1169 upgrade will perform the following actions:
1155 upgrade will perform the following actions:
1170
1156
1171 requirements
1157 requirements
1172 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1158 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1173
1159
1174 optimisations: re-delta-all
1160 optimisations: re-delta-all
1175
1161
1176 re-delta-all
1162 re-delta-all
1177 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1163 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1178
1164
1179 processed revlogs:
1165 processed revlogs:
1180 - all-filelogs
1166 - all-filelogs
1181 - changelog
1167 - changelog
1182 - manifest
1168 - manifest
1183
1169
1184 beginning upgrade...
1170 beginning upgrade...
1185 repository locked and read-only
1171 repository locked and read-only
1186 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1172 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1187 (it is safe to interrupt this process any time before data migration completes)
1173 (it is safe to interrupt this process any time before data migration completes)
1188 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1174 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1189 migrating 1019 bytes in store; 882 bytes tracked data
1175 migrating 1019 bytes in store; 882 bytes tracked data
1190 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1176 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1191 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1177 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1192 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1178 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1193 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1179 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1194 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1180 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1195 finished migrating 3 changelog revisions; change in size: 0 bytes
1181 finished migrating 3 changelog revisions; change in size: 0 bytes
1196 finished migrating 9 total revisions; total change in store size: -9 bytes
1182 finished migrating 9 total revisions; total change in store size: -9 bytes
1197 copying phaseroots
1183 copying phaseroots
1198 data fully upgraded in a temporary repository
1184 data fully upgraded in a temporary repository
1199 marking source repository as being upgraded; clients will be unable to read from repository
1185 marking source repository as being upgraded; clients will be unable to read from repository
1200 starting in-place swap of repository data
1186 starting in-place swap of repository data
1201 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1187 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1202 replacing store...
1188 replacing store...
1203 store replacement complete; repository was inconsistent for *s (glob)
1189 store replacement complete; repository was inconsistent for *s (glob)
1204 finalizing requirements file and making repository readable again
1190 finalizing requirements file and making repository readable again
1205 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1191 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1206 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1192 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1207 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1193 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1208 $ hg debugdeltachain file
1194 $ hg debugdeltachain file
1209 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1195 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1210 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1196 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1211 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1197 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1212 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1198 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1213 $ cd ..
1199 $ cd ..
1214
1200
1215 $ cat << EOF >> $HGRCPATH
1201 $ cat << EOF >> $HGRCPATH
1216 > [format]
1202 > [format]
1217 > maxchainlen = 9001
1203 > maxchainlen = 9001
1218 > EOF
1204 > EOF
1219
1205
1220 Check upgrading a sparse-revlog repository
1206 Check upgrading a sparse-revlog repository
1221 ---------------------------------------
1207 ---------------------------------------
1222
1208
1223 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1209 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1224 $ cd sparserevlogrepo
1210 $ cd sparserevlogrepo
1225 $ touch foo
1211 $ touch foo
1226 $ hg add foo
1212 $ hg add foo
1227 $ hg -q commit -m "foo"
1213 $ hg -q commit -m "foo"
1228 $ cat .hg/requires
1214 $ cat .hg/requires
1229 dotencode
1215 dotencode
1230 fncache
1216 fncache
1231 generaldelta
1217 generaldelta
1232 revlogv1
1218 revlogv1
1233 store
1219 store
1234
1220
1235 Check that we can add the sparse-revlog format requirement
1221 Check that we can add the sparse-revlog format requirement
1236 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1222 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1237 upgrade will perform the following actions:
1223 upgrade will perform the following actions:
1238
1224
1239 requirements
1225 requirements
1240 preserved: dotencode, fncache, generaldelta, revlogv1, store
1226 preserved: dotencode, fncache, generaldelta, revlogv1, store
1241 added: sparserevlog
1227 added: sparserevlog
1242
1228
1243 processed revlogs:
1229 processed revlogs:
1244 - all-filelogs
1230 - all-filelogs
1245 - changelog
1231 - changelog
1246 - manifest
1232 - manifest
1247
1233
1248 $ cat .hg/requires
1234 $ cat .hg/requires
1249 dotencode
1235 dotencode
1250 fncache
1236 fncache
1251 generaldelta
1237 generaldelta
1252 revlogv1
1238 revlogv1
1253 sparserevlog
1239 sparserevlog
1254 store
1240 store
1255
1241
1256 Check that we can remove the sparse-revlog format requirement
1242 Check that we can remove the sparse-revlog format requirement
1257 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1243 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1258 upgrade will perform the following actions:
1244 upgrade will perform the following actions:
1259
1245
1260 requirements
1246 requirements
1261 preserved: dotencode, fncache, generaldelta, revlogv1, store
1247 preserved: dotencode, fncache, generaldelta, revlogv1, store
1262 removed: sparserevlog
1248 removed: sparserevlog
1263
1249
1264 processed revlogs:
1250 processed revlogs:
1265 - all-filelogs
1251 - all-filelogs
1266 - changelog
1252 - changelog
1267 - manifest
1253 - manifest
1268
1254
1269 $ cat .hg/requires
1255 $ cat .hg/requires
1270 dotencode
1256 dotencode
1271 fncache
1257 fncache
1272 generaldelta
1258 generaldelta
1273 revlogv1
1259 revlogv1
1274 store
1260 store
1275
1261
1276 #if zstd
1262 #if zstd
1277
1263
1278 Check upgrading to a zstd revlog
1264 Check upgrading to a zstd revlog
1279 --------------------------------
1265 --------------------------------
1280
1266
1281 upgrade
1267 upgrade
1282
1268
1283 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1269 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1284 upgrade will perform the following actions:
1270 upgrade will perform the following actions:
1285
1271
1286 requirements
1272 requirements
1287 preserved: dotencode, fncache, generaldelta, revlogv1, store
1273 preserved: dotencode, fncache, generaldelta, revlogv1, store
1288 added: revlog-compression-zstd, sparserevlog
1274 added: revlog-compression-zstd, sparserevlog
1289
1275
1290 processed revlogs:
1276 processed revlogs:
1291 - all-filelogs
1277 - all-filelogs
1292 - changelog
1278 - changelog
1293 - manifest
1279 - manifest
1294
1280
1295 $ hg debugformat -v
1281 $ hg debugformat -v
1296 format-variant repo config default
1282 format-variant repo config default
1297 fncache: yes yes yes
1283 fncache: yes yes yes
1298 dotencode: yes yes yes
1284 dotencode: yes yes yes
1299 generaldelta: yes yes yes
1285 generaldelta: yes yes yes
1300 share-safe: no no no
1286 share-safe: no no no
1301 sparserevlog: yes yes yes
1287 sparserevlog: yes yes yes
1302 sidedata: no no no
1288 sidedata: no no no
1303 persistent-nodemap: no no no
1289 persistent-nodemap: no no no
1304 copies-sdc: no no no
1290 copies-sdc: no no no
1305 plain-cl-delta: yes yes yes
1291 plain-cl-delta: yes yes yes
1306 compression: zstd zlib zlib
1292 compression: zstd zlib zlib
1307 compression-level: default default default
1293 compression-level: default default default
1308 $ cat .hg/requires
1294 $ cat .hg/requires
1309 dotencode
1295 dotencode
1310 fncache
1296 fncache
1311 generaldelta
1297 generaldelta
1312 revlog-compression-zstd
1298 revlog-compression-zstd
1313 revlogv1
1299 revlogv1
1314 sparserevlog
1300 sparserevlog
1315 store
1301 store
1316
1302
1317 downgrade
1303 downgrade
1318
1304
1319 $ hg debugupgraderepo --run --no-backup --quiet
1305 $ hg debugupgraderepo --run --no-backup --quiet
1320 upgrade will perform the following actions:
1306 upgrade will perform the following actions:
1321
1307
1322 requirements
1308 requirements
1323 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1309 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1324 removed: revlog-compression-zstd
1310 removed: revlog-compression-zstd
1325
1311
1326 processed revlogs:
1312 processed revlogs:
1327 - all-filelogs
1313 - all-filelogs
1328 - changelog
1314 - changelog
1329 - manifest
1315 - manifest
1330
1316
1331 $ hg debugformat -v
1317 $ hg debugformat -v
1332 format-variant repo config default
1318 format-variant repo config default
1333 fncache: yes yes yes
1319 fncache: yes yes yes
1334 dotencode: yes yes yes
1320 dotencode: yes yes yes
1335 generaldelta: yes yes yes
1321 generaldelta: yes yes yes
1336 share-safe: no no no
1322 share-safe: no no no
1337 sparserevlog: yes yes yes
1323 sparserevlog: yes yes yes
1338 sidedata: no no no
1324 sidedata: no no no
1339 persistent-nodemap: no no no
1325 persistent-nodemap: no no no
1340 copies-sdc: no no no
1326 copies-sdc: no no no
1341 plain-cl-delta: yes yes yes
1327 plain-cl-delta: yes yes yes
1342 compression: zlib zlib zlib
1328 compression: zlib zlib zlib
1343 compression-level: default default default
1329 compression-level: default default default
1344 $ cat .hg/requires
1330 $ cat .hg/requires
1345 dotencode
1331 dotencode
1346 fncache
1332 fncache
1347 generaldelta
1333 generaldelta
1348 revlogv1
1334 revlogv1
1349 sparserevlog
1335 sparserevlog
1350 store
1336 store
1351
1337
1352 upgrade from hgrc
1338 upgrade from hgrc
1353
1339
1354 $ cat >> .hg/hgrc << EOF
1340 $ cat >> .hg/hgrc << EOF
1355 > [format]
1341 > [format]
1356 > revlog-compression=zstd
1342 > revlog-compression=zstd
1357 > EOF
1343 > EOF
1358 $ hg debugupgraderepo --run --no-backup --quiet
1344 $ hg debugupgraderepo --run --no-backup --quiet
1359 upgrade will perform the following actions:
1345 upgrade will perform the following actions:
1360
1346
1361 requirements
1347 requirements
1362 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1348 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1363 added: revlog-compression-zstd
1349 added: revlog-compression-zstd
1364
1350
1365 processed revlogs:
1351 processed revlogs:
1366 - all-filelogs
1352 - all-filelogs
1367 - changelog
1353 - changelog
1368 - manifest
1354 - manifest
1369
1355
1370 $ hg debugformat -v
1356 $ hg debugformat -v
1371 format-variant repo config default
1357 format-variant repo config default
1372 fncache: yes yes yes
1358 fncache: yes yes yes
1373 dotencode: yes yes yes
1359 dotencode: yes yes yes
1374 generaldelta: yes yes yes
1360 generaldelta: yes yes yes
1375 share-safe: no no no
1361 share-safe: no no no
1376 sparserevlog: yes yes yes
1362 sparserevlog: yes yes yes
1377 sidedata: no no no
1363 sidedata: no no no
1378 persistent-nodemap: no no no
1364 persistent-nodemap: no no no
1379 copies-sdc: no no no
1365 copies-sdc: no no no
1380 plain-cl-delta: yes yes yes
1366 plain-cl-delta: yes yes yes
1381 compression: zstd zstd zlib
1367 compression: zstd zstd zlib
1382 compression-level: default default default
1368 compression-level: default default default
1383 $ cat .hg/requires
1369 $ cat .hg/requires
1384 dotencode
1370 dotencode
1385 fncache
1371 fncache
1386 generaldelta
1372 generaldelta
1387 revlog-compression-zstd
1373 revlog-compression-zstd
1388 revlogv1
1374 revlogv1
1389 sparserevlog
1375 sparserevlog
1390 store
1376 store
1391
1377
1392 #endif
1378 #endif
1393
1379
1394 Check upgrading to a side-data revlog
1380 Check upgrading to a side-data revlog
1395 -------------------------------------
1381 -------------------------------------
1396
1382
1397 upgrade
1383 upgrade
1398
1384
1399 $ hg --config format.exp-use-side-data=yes debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1385 $ hg --config format.exp-use-side-data=yes debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1400 upgrade will perform the following actions:
1386 upgrade will perform the following actions:
1401
1387
1402 requirements
1388 requirements
1403 preserved: dotencode, fncache, generaldelta, revlogv1, store (no-zstd !)
1389 preserved: dotencode, fncache, generaldelta, revlogv1, store (no-zstd !)
1404 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1390 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1405 added: exp-sidedata-flag (zstd !)
1391 added: exp-sidedata-flag (zstd !)
1406 added: exp-sidedata-flag, sparserevlog (no-zstd !)
1392 added: exp-sidedata-flag, sparserevlog (no-zstd !)
1407
1393
1408 processed revlogs:
1394 processed revlogs:
1409 - all-filelogs
1395 - all-filelogs
1410 - changelog
1396 - changelog
1411 - manifest
1397 - manifest
1412
1398
1413 $ hg debugformat -v
1399 $ hg debugformat -v
1414 format-variant repo config default
1400 format-variant repo config default
1415 fncache: yes yes yes
1401 fncache: yes yes yes
1416 dotencode: yes yes yes
1402 dotencode: yes yes yes
1417 generaldelta: yes yes yes
1403 generaldelta: yes yes yes
1418 share-safe: no no no
1404 share-safe: no no no
1419 sparserevlog: yes yes yes
1405 sparserevlog: yes yes yes
1420 sidedata: yes no no
1406 sidedata: yes no no
1421 persistent-nodemap: no no no
1407 persistent-nodemap: no no no
1422 copies-sdc: no no no
1408 copies-sdc: no no no
1423 plain-cl-delta: yes yes yes
1409 plain-cl-delta: yes yes yes
1424 compression: zlib zlib zlib (no-zstd !)
1410 compression: zlib zlib zlib (no-zstd !)
1425 compression: zstd zstd zlib (zstd !)
1411 compression: zstd zstd zlib (zstd !)
1426 compression-level: default default default
1412 compression-level: default default default
1427 $ cat .hg/requires
1413 $ cat .hg/requires
1428 dotencode
1414 dotencode
1429 exp-sidedata-flag
1415 exp-sidedata-flag
1430 fncache
1416 fncache
1431 generaldelta
1417 generaldelta
1432 revlog-compression-zstd (zstd !)
1418 revlog-compression-zstd (zstd !)
1433 revlogv1
1419 revlogv1
1434 sparserevlog
1420 sparserevlog
1435 store
1421 store
1436 $ hg debugsidedata -c 0
1422 $ hg debugsidedata -c 0
1437 2 sidedata entries
1423 2 sidedata entries
1438 entry-0001 size 4
1424 entry-0001 size 4
1439 entry-0002 size 32
1425 entry-0002 size 32
1440
1426
1441 downgrade
1427 downgrade
1442
1428
1443 $ hg debugupgraderepo --config format.exp-use-side-data=no --run --no-backup --quiet
1429 $ hg debugupgraderepo --config format.exp-use-side-data=no --run --no-backup --quiet
1444 upgrade will perform the following actions:
1430 upgrade will perform the following actions:
1445
1431
1446 requirements
1432 requirements
1447 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1433 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1448 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1434 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1449 removed: exp-sidedata-flag
1435 removed: exp-sidedata-flag
1450
1436
1451 processed revlogs:
1437 processed revlogs:
1452 - all-filelogs
1438 - all-filelogs
1453 - changelog
1439 - changelog
1454 - manifest
1440 - manifest
1455
1441
1456 $ hg debugformat -v
1442 $ hg debugformat -v
1457 format-variant repo config default
1443 format-variant repo config default
1458 fncache: yes yes yes
1444 fncache: yes yes yes
1459 dotencode: yes yes yes
1445 dotencode: yes yes yes
1460 generaldelta: yes yes yes
1446 generaldelta: yes yes yes
1461 share-safe: no no no
1447 share-safe: no no no
1462 sparserevlog: yes yes yes
1448 sparserevlog: yes yes yes
1463 sidedata: no no no
1449 sidedata: no no no
1464 persistent-nodemap: no no no
1450 persistent-nodemap: no no no
1465 copies-sdc: no no no
1451 copies-sdc: no no no
1466 plain-cl-delta: yes yes yes
1452 plain-cl-delta: yes yes yes
1467 compression: zlib zlib zlib (no-zstd !)
1453 compression: zlib zlib zlib (no-zstd !)
1468 compression: zstd zstd zlib (zstd !)
1454 compression: zstd zstd zlib (zstd !)
1469 compression-level: default default default
1455 compression-level: default default default
1470 $ cat .hg/requires
1456 $ cat .hg/requires
1471 dotencode
1457 dotencode
1472 fncache
1458 fncache
1473 generaldelta
1459 generaldelta
1474 revlog-compression-zstd (zstd !)
1460 revlog-compression-zstd (zstd !)
1475 revlogv1
1461 revlogv1
1476 sparserevlog
1462 sparserevlog
1477 store
1463 store
1478 $ hg debugsidedata -c 0
1464 $ hg debugsidedata -c 0
1479
1465
1480 upgrade from hgrc
1466 upgrade from hgrc
1481
1467
1482 $ cat >> .hg/hgrc << EOF
1468 $ cat >> .hg/hgrc << EOF
1483 > [format]
1469 > [format]
1484 > exp-use-side-data=yes
1470 > exp-use-side-data=yes
1485 > EOF
1471 > EOF
1486 $ hg debugupgraderepo --run --no-backup --quiet
1472 $ hg debugupgraderepo --run --no-backup --quiet
1487 upgrade will perform the following actions:
1473 upgrade will perform the following actions:
1488
1474
1489 requirements
1475 requirements
1490 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1476 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1491 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1477 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1492 added: exp-sidedata-flag
1478 added: exp-sidedata-flag
1493
1479
1494 processed revlogs:
1480 processed revlogs:
1495 - all-filelogs
1481 - all-filelogs
1496 - changelog
1482 - changelog
1497 - manifest
1483 - manifest
1498
1484
1499 $ hg debugformat -v
1485 $ hg debugformat -v
1500 format-variant repo config default
1486 format-variant repo config default
1501 fncache: yes yes yes
1487 fncache: yes yes yes
1502 dotencode: yes yes yes
1488 dotencode: yes yes yes
1503 generaldelta: yes yes yes
1489 generaldelta: yes yes yes
1504 share-safe: no no no
1490 share-safe: no no no
1505 sparserevlog: yes yes yes
1491 sparserevlog: yes yes yes
1506 sidedata: yes yes no
1492 sidedata: yes yes no
1507 persistent-nodemap: no no no
1493 persistent-nodemap: no no no
1508 copies-sdc: no no no
1494 copies-sdc: no no no
1509 plain-cl-delta: yes yes yes
1495 plain-cl-delta: yes yes yes
1510 compression: zlib zlib zlib (no-zstd !)
1496 compression: zlib zlib zlib (no-zstd !)
1511 compression: zstd zstd zlib (zstd !)
1497 compression: zstd zstd zlib (zstd !)
1512 compression-level: default default default
1498 compression-level: default default default
1513 $ cat .hg/requires
1499 $ cat .hg/requires
1514 dotencode
1500 dotencode
1515 exp-sidedata-flag
1501 exp-sidedata-flag
1516 fncache
1502 fncache
1517 generaldelta
1503 generaldelta
1518 revlog-compression-zstd (zstd !)
1504 revlog-compression-zstd (zstd !)
1519 revlogv1
1505 revlogv1
1520 sparserevlog
1506 sparserevlog
1521 store
1507 store
1522 $ hg debugsidedata -c 0
1508 $ hg debugsidedata -c 0
1523
1509
1524 Demonstrate that nothing to perform upgrade will still run all the way through
1510 Demonstrate that nothing to perform upgrade will still run all the way through
1525
1511
1526 $ hg debugupgraderepo --run
1512 $ hg debugupgraderepo --run
1527 nothing to do
1513 nothing to do
General Comments 0
You need to be logged in to leave comments. Login now