##// END OF EJS Templates
upgrade: prepare code (and output) for the idea of upgrading share...
marmoute -
r49628:17eaeb06 default
parent child Browse files
Show More
@@ -1,401 +1,417 b''
1 1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 2 #
3 3 # Copyright (c) 2016-present, Gregory Szorc
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from .i18n import _
11 11 from . import (
12 12 error,
13 13 hg,
14 14 localrepo,
15 15 lock as lockmod,
16 16 pycompat,
17 17 requirements as requirementsmod,
18 18 scmutil,
19 19 )
20 20
21 21 from .upgrade_utils import (
22 22 actions as upgrade_actions,
23 23 engine as upgrade_engine,
24 24 )
25 25
26 26 from .utils import (
27 27 stringutil,
28 28 )
29 29
30 30 allformatvariant = upgrade_actions.allformatvariant
31 31
32 32
33 33 def upgraderepo(
34 34 ui,
35 35 repo,
36 36 run=False,
37 37 optimize=None,
38 38 backup=True,
39 39 manifest=None,
40 40 changelog=None,
41 41 filelogs=None,
42 42 ):
43 43 """Upgrade a repository in place."""
44 44 if optimize is None:
45 45 optimize = set()
46 46 repo = repo.unfiltered()
47 47
48 48 specified_revlogs = {}
49 49 if changelog is not None:
50 50 specified_revlogs[upgrade_engine.UPGRADE_CHANGELOG] = changelog
51 51 if manifest is not None:
52 52 specified_revlogs[upgrade_engine.UPGRADE_MANIFEST] = manifest
53 53 if filelogs is not None:
54 54 specified_revlogs[upgrade_engine.UPGRADE_FILELOGS] = filelogs
55 55
56 56 # Ensure the repository can be upgraded.
57 57 upgrade_actions.check_source_requirements(repo)
58 58
59 59 default_options = localrepo.defaultcreateopts(repo.ui)
60 60 newreqs = localrepo.newreporequirements(repo.ui, default_options)
61 61 newreqs.update(upgrade_actions.preservedrequirements(repo))
62 62
63 63 upgrade_actions.check_requirements_changes(repo, newreqs)
64 64
65 65 # Find and validate all improvements that can be made.
66 66 alloptimizations = upgrade_actions.findoptimizations(repo)
67 67
68 68 # Apply and Validate arguments.
69 69 optimizations = []
70 70 for o in alloptimizations:
71 71 if o.name in optimize:
72 72 optimizations.append(o)
73 73 optimize.discard(o.name)
74 74
75 75 if optimize: # anything left is unknown
76 76 raise error.Abort(
77 77 _(b'unknown optimization action requested: %s')
78 78 % b', '.join(sorted(optimize)),
79 79 hint=_(b'run without arguments to see valid optimizations'),
80 80 )
81 81
82 82 format_upgrades = upgrade_actions.find_format_upgrades(repo)
83 83 up_actions = upgrade_actions.determine_upgrade_actions(
84 84 repo, format_upgrades, optimizations, repo.requirements, newreqs
85 85 )
86 86 removed_actions = upgrade_actions.find_format_downgrades(repo)
87 87
88 88 # check if we need to touch revlog and if so, which ones
89 89
90 90 touched_revlogs = set()
91 91 overwrite_msg = _(b'warning: ignoring %14s, as upgrade is changing: %s\n')
92 92 select_msg = _(b'note: selecting %s for processing to change: %s\n')
93 93 msg_issued = 0
94 94
95 95 FL = upgrade_engine.UPGRADE_FILELOGS
96 96 MN = upgrade_engine.UPGRADE_MANIFEST
97 97 CL = upgrade_engine.UPGRADE_CHANGELOG
98 98
99 99 if optimizations:
100 100 if any(specified_revlogs.values()):
101 101 # we have some limitation on revlogs to be recloned
102 102 for rl, enabled in specified_revlogs.items():
103 103 if enabled:
104 104 touched_revlogs.add(rl)
105 105 else:
106 106 touched_revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
107 107 for rl, enabled in specified_revlogs.items():
108 108 if not enabled:
109 109 touched_revlogs.discard(rl)
110 110
111 if repo.shared():
112 unsafe_actions = set()
113 unsafe_actions.update(up_actions)
114 unsafe_actions.update(removed_actions)
115 unsafe_actions.update(optimizations)
116 unsafe_actions = [
117 a for a in unsafe_actions if not a.compatible_with_share
118 ]
119 unsafe_actions.sort(key=lambda a: a.name)
120 if unsafe_actions:
121 m = _(b'cannot use these actions on a share repository: %s')
122 h = _(b'upgrade the main repository directly')
123 actions = b', '.join(a.name for a in unsafe_actions)
124 m %= actions
125 raise error.Abort(m, hint=h)
126
111 127 for action in sorted(up_actions + removed_actions, key=lambda a: a.name):
112 128 # optimisation does not "requires anything, they just needs it.
113 129 if action.type != upgrade_actions.FORMAT_VARIANT:
114 130 continue
115 131
116 132 if action.touches_filelogs and FL not in touched_revlogs:
117 133 if FL in specified_revlogs:
118 134 if not specified_revlogs[FL]:
119 135 msg = overwrite_msg % (b'--no-filelogs', action.name)
120 136 ui.warn(msg)
121 137 msg_issued = 2
122 138 else:
123 139 msg = select_msg % (b'all-filelogs', action.name)
124 140 ui.status(msg)
125 141 if not ui.quiet:
126 142 msg_issued = 1
127 143 touched_revlogs.add(FL)
128 144
129 145 if action.touches_manifests and MN not in touched_revlogs:
130 146 if MN in specified_revlogs:
131 147 if not specified_revlogs[MN]:
132 148 msg = overwrite_msg % (b'--no-manifest', action.name)
133 149 ui.warn(msg)
134 150 msg_issued = 2
135 151 else:
136 152 msg = select_msg % (b'all-manifestlogs', action.name)
137 153 ui.status(msg)
138 154 if not ui.quiet:
139 155 msg_issued = 1
140 156 touched_revlogs.add(MN)
141 157
142 158 if action.touches_changelog and CL not in touched_revlogs:
143 159 if CL in specified_revlogs:
144 160 if not specified_revlogs[CL]:
145 161 msg = overwrite_msg % (b'--no-changelog', action.name)
146 162 ui.warn(msg)
147 163 msg_issued = True
148 164 else:
149 165 msg = select_msg % (b'changelog', action.name)
150 166 ui.status(msg)
151 167 if not ui.quiet:
152 168 msg_issued = 1
153 169 touched_revlogs.add(CL)
154 170 if msg_issued >= 2:
155 171 ui.warn((b"\n"))
156 172 elif msg_issued >= 1:
157 173 ui.status((b"\n"))
158 174
159 175 upgrade_op = upgrade_actions.UpgradeOperation(
160 176 ui,
161 177 newreqs,
162 178 repo.requirements,
163 179 up_actions,
164 180 removed_actions,
165 181 touched_revlogs,
166 182 backup,
167 183 )
168 184
169 185 if not run:
170 186 fromconfig = []
171 187 onlydefault = []
172 188
173 189 for d in format_upgrades:
174 190 if d.fromconfig(repo):
175 191 fromconfig.append(d)
176 192 elif d.default:
177 193 onlydefault.append(d)
178 194
179 195 if fromconfig or onlydefault:
180 196
181 197 if fromconfig:
182 198 ui.status(
183 199 _(
184 200 b'repository lacks features recommended by '
185 201 b'current config options:\n\n'
186 202 )
187 203 )
188 204 for i in fromconfig:
189 205 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
190 206
191 207 if onlydefault:
192 208 ui.status(
193 209 _(
194 210 b'repository lacks features used by the default '
195 211 b'config options:\n\n'
196 212 )
197 213 )
198 214 for i in onlydefault:
199 215 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
200 216
201 217 ui.status(b'\n')
202 218 else:
203 219 ui.status(_(b'(no format upgrades found in existing repository)\n'))
204 220
205 221 ui.status(
206 222 _(
207 223 b'performing an upgrade with "--run" will make the following '
208 224 b'changes:\n\n'
209 225 )
210 226 )
211 227
212 228 upgrade_op.print_requirements()
213 229 upgrade_op.print_optimisations()
214 230 upgrade_op.print_upgrade_actions()
215 231 upgrade_op.print_affected_revlogs()
216 232
217 233 if upgrade_op.unused_optimizations:
218 234 ui.status(
219 235 _(
220 236 b'additional optimizations are available by specifying '
221 237 b'"--optimize <name>":\n\n'
222 238 )
223 239 )
224 240 upgrade_op.print_unused_optimizations()
225 241 return
226 242
227 243 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
228 244 ui.status(_(b'nothing to do\n'))
229 245 return
230 246 # Else we're in the run=true case.
231 247 ui.write(_(b'upgrade will perform the following actions:\n\n'))
232 248 upgrade_op.print_requirements()
233 249 upgrade_op.print_optimisations()
234 250 upgrade_op.print_upgrade_actions()
235 251 upgrade_op.print_affected_revlogs()
236 252
237 253 ui.status(_(b'beginning upgrade...\n'))
238 254 with repo.wlock(), repo.lock():
239 255 ui.status(_(b'repository locked and read-only\n'))
240 256 # Our strategy for upgrading the repository is to create a new,
241 257 # temporary repository, write data to it, then do a swap of the
242 258 # data. There are less heavyweight ways to do this, but it is easier
243 259 # to create a new repo object than to instantiate all the components
244 260 # (like the store) separately.
245 261 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
246 262 backuppath = None
247 263 try:
248 264 ui.status(
249 265 _(
250 266 b'creating temporary repository to stage upgraded '
251 267 b'data: %s\n'
252 268 )
253 269 % tmppath
254 270 )
255 271
256 272 # clone ui without using ui.copy because repo.ui is protected
257 273 repoui = repo.ui.__class__(repo.ui)
258 274 dstrepo = hg.repository(repoui, path=tmppath, create=True)
259 275
260 276 with dstrepo.wlock(), dstrepo.lock():
261 277 backuppath = upgrade_engine.upgrade(
262 278 ui, repo, dstrepo, upgrade_op
263 279 )
264 280
265 281 finally:
266 282 ui.status(_(b'removing temporary repository %s\n') % tmppath)
267 283 repo.vfs.rmtree(tmppath, forcibly=True)
268 284
269 285 if backuppath and not ui.quiet:
270 286 ui.warn(
271 287 _(b'copy of old repository backed up at %s\n') % backuppath
272 288 )
273 289 ui.warn(
274 290 _(
275 291 b'the old repository will not be deleted; remove '
276 292 b'it to free up disk space once the upgraded '
277 293 b'repository is verified\n'
278 294 )
279 295 )
280 296
281 297 upgrade_op.print_post_op_messages()
282 298
283 299
284 300 def upgrade_share_to_safe(
285 301 ui,
286 302 hgvfs,
287 303 storevfs,
288 304 current_requirements,
289 305 mismatch_config,
290 306 mismatch_warn,
291 307 ):
292 308 """Upgrades a share to use share-safe mechanism"""
293 309 wlock = None
294 310 store_requirements = localrepo._readrequires(storevfs, False)
295 311 original_crequirements = current_requirements.copy()
296 312 # after upgrade, store requires will be shared, so lets find
297 313 # the requirements which are not present in store and
298 314 # write them to share's .hg/requires
299 315 diffrequires = current_requirements - store_requirements
300 316 # add share-safe requirement as it will mark the share as share-safe
301 317 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
302 318 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
303 319 # in `allow` case, we don't try to upgrade, we just respect the source
304 320 # state, update requirements and continue
305 321 if mismatch_config == b'allow':
306 322 return
307 323 try:
308 324 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
309 325 # some process might change the requirement in between, re-read
310 326 # and update current_requirements
311 327 locked_requirements = localrepo._readrequires(hgvfs, True)
312 328 if locked_requirements != original_crequirements:
313 329 removed = current_requirements - locked_requirements
314 330 # update current_requirements in place because it's passed
315 331 # as reference
316 332 current_requirements -= removed
317 333 current_requirements |= locked_requirements
318 334 diffrequires = current_requirements - store_requirements
319 335 # add share-safe requirement as it will mark the share as share-safe
320 336 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
321 337 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
322 338 scmutil.writerequires(hgvfs, diffrequires)
323 339 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
324 340 except error.LockError as e:
325 341 hint = _(
326 342 b"see `hg help config.format.use-share-safe` for more information"
327 343 )
328 344 if mismatch_config == b'upgrade-abort':
329 345 raise error.Abort(
330 346 _(b'failed to upgrade share, got error: %s')
331 347 % stringutil.forcebytestr(e.strerror),
332 348 hint=hint,
333 349 )
334 350 elif mismatch_warn:
335 351 ui.warn(
336 352 _(b'failed to upgrade share, got error: %s\n')
337 353 % stringutil.forcebytestr(e.strerror),
338 354 hint=hint,
339 355 )
340 356 finally:
341 357 if wlock:
342 358 wlock.release()
343 359
344 360
345 361 def downgrade_share_to_non_safe(
346 362 ui,
347 363 hgvfs,
348 364 sharedvfs,
349 365 current_requirements,
350 366 mismatch_config,
351 367 mismatch_warn,
352 368 ):
353 369 """Downgrades a share which use share-safe to not use it"""
354 370 wlock = None
355 371 source_requirements = localrepo._readrequires(sharedvfs, True)
356 372 original_crequirements = current_requirements.copy()
357 373 # we cannot be 100% sure on which requirements were present in store when
358 374 # the source supported share-safe. However, we do know that working
359 375 # directory requirements were not there. Hence we remove them
360 376 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
361 377 current_requirements |= source_requirements
362 378 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
363 379 if mismatch_config == b'allow':
364 380 return
365 381
366 382 try:
367 383 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
368 384 # some process might change the requirement in between, re-read
369 385 # and update current_requirements
370 386 locked_requirements = localrepo._readrequires(hgvfs, True)
371 387 if locked_requirements != original_crequirements:
372 388 removed = current_requirements - locked_requirements
373 389 # update current_requirements in place because it's passed
374 390 # as reference
375 391 current_requirements -= removed
376 392 current_requirements |= locked_requirements
377 393 current_requirements |= source_requirements
378 394 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
379 395 scmutil.writerequires(hgvfs, current_requirements)
380 396 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
381 397 except error.LockError as e:
382 398 hint = _(
383 399 b"see `hg help config.format.use-share-safe` for more information"
384 400 )
385 401 # If upgrade-abort is set, abort when upgrade fails, else let the
386 402 # process continue as `upgrade-allow` is set
387 403 if mismatch_config == b'downgrade-abort':
388 404 raise error.Abort(
389 405 _(b'failed to downgrade share, got error: %s')
390 406 % stringutil.forcebytestr(e.strerror),
391 407 hint=hint,
392 408 )
393 409 elif mismatch_warn:
394 410 ui.warn(
395 411 _(b'failed to downgrade share, got error: %s\n')
396 412 % stringutil.forcebytestr(e.strerror),
397 413 hint=hint,
398 414 )
399 415 finally:
400 416 if wlock:
401 417 wlock.release()
@@ -1,1054 +1,1069 b''
1 1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 2 #
3 3 # Copyright (c) 2016-present, Gregory Szorc
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from ..i18n import _
11 11 from .. import (
12 12 error,
13 13 localrepo,
14 14 pycompat,
15 15 requirements,
16 16 revlog,
17 17 util,
18 18 )
19 19
20 20 from ..utils import compression
21 21
22 22 if pycompat.TYPE_CHECKING:
23 23 from typing import (
24 24 List,
25 25 Type,
26 26 )
27 27
28 28
29 29 # list of requirements that request a clone of all revlog if added/removed
30 30 RECLONES_REQUIREMENTS = {
31 31 requirements.GENERALDELTA_REQUIREMENT,
32 32 requirements.SPARSEREVLOG_REQUIREMENT,
33 33 requirements.REVLOGV2_REQUIREMENT,
34 34 requirements.CHANGELOGV2_REQUIREMENT,
35 35 }
36 36
37 37
38 38 def preservedrequirements(repo):
39 return set()
39 preserved = {
40 requirements.SHARED_REQUIREMENT,
41 }
42 return preserved & repo.requirements
40 43
41 44
42 45 FORMAT_VARIANT = b'deficiency'
43 46 OPTIMISATION = b'optimization'
44 47
45 48
46 49 class improvement(object):
47 50 """Represents an improvement that can be made as part of an upgrade."""
48 51
49 52 ### The following attributes should be defined for each subclass:
50 53
51 54 # Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
52 55 # A format variant is where we change the storage format. Not all format
53 56 # variant changes are an obvious problem.
54 57 # An optimization is an action (sometimes optional) that
55 58 # can be taken to further improve the state of the repository.
56 59 type = None
57 60
58 61 # machine-readable string uniquely identifying this improvement. it will be
59 62 # mapped to an action later in the upgrade process.
60 63 name = None
61 64
62 65 # message intended for humans explaining the improvement in more detail,
63 66 # including the implications of it ``FORMAT_VARIANT`` types, should be
64 67 # worded
65 68 # in the present tense.
66 69 description = None
67 70
68 71 # message intended for humans explaining what an upgrade addressing this
69 72 # issue will do. should be worded in the future tense.
70 73 upgrademessage = None
71 74
72 75 # value of current Mercurial default for new repository
73 76 default = None
74 77
75 78 # Message intended for humans which will be shown post an upgrade
76 79 # operation when the improvement will be added
77 80 postupgrademessage = None
78 81
79 82 # Message intended for humans which will be shown post an upgrade
80 83 # operation in which this improvement was removed
81 84 postdowngrademessage = None
82 85
83 86 # By default we assume that every improvement touches requirements and all revlogs
84 87
85 88 # Whether this improvement touches filelogs
86 89 touches_filelogs = True
87 90
88 91 # Whether this improvement touches manifests
89 92 touches_manifests = True
90 93
91 94 # Whether this improvement touches changelog
92 95 touches_changelog = True
93 96
94 97 # Whether this improvement changes repository requirements
95 98 touches_requirements = True
96 99
97 100 # Whether this improvement touches the dirstate
98 101 touches_dirstate = False
99 102
103 # Can this action be run on a share instead of its mains repository
104 compatible_with_share = False
105
100 106
101 107 allformatvariant = [] # type: List[Type['formatvariant']]
102 108
103 109
104 110 def registerformatvariant(cls):
105 111 allformatvariant.append(cls)
106 112 return cls
107 113
108 114
109 115 class formatvariant(improvement):
110 116 """an improvement subclass dedicated to repository format"""
111 117
112 118 type = FORMAT_VARIANT
113 119
114 120 @staticmethod
115 121 def fromrepo(repo):
116 122 """current value of the variant in the repository"""
117 123 raise NotImplementedError()
118 124
119 125 @staticmethod
120 126 def fromconfig(repo):
121 127 """current value of the variant in the configuration"""
122 128 raise NotImplementedError()
123 129
124 130
125 131 class requirementformatvariant(formatvariant):
126 132 """formatvariant based on a 'requirement' name.
127 133
128 134 Many format variant are controlled by a 'requirement'. We define a small
129 135 subclass to factor the code.
130 136 """
131 137
132 138 # the requirement that control this format variant
133 139 _requirement = None
134 140
135 141 @staticmethod
136 142 def _newreporequirements(ui):
137 143 return localrepo.newreporequirements(
138 144 ui, localrepo.defaultcreateopts(ui)
139 145 )
140 146
141 147 @classmethod
142 148 def fromrepo(cls, repo):
143 149 assert cls._requirement is not None
144 150 return cls._requirement in repo.requirements
145 151
146 152 @classmethod
147 153 def fromconfig(cls, repo):
148 154 assert cls._requirement is not None
149 155 return cls._requirement in cls._newreporequirements(repo.ui)
150 156
151 157
152 158 @registerformatvariant
153 159 class fncache(requirementformatvariant):
154 160 name = b'fncache'
155 161
156 162 _requirement = requirements.FNCACHE_REQUIREMENT
157 163
158 164 default = True
159 165
160 166 description = _(
161 167 b'long and reserved filenames may not work correctly; '
162 168 b'repository performance is sub-optimal'
163 169 )
164 170
165 171 upgrademessage = _(
166 172 b'repository will be more resilient to storing '
167 173 b'certain paths and performance of certain '
168 174 b'operations should be improved'
169 175 )
170 176
171 177
172 178 @registerformatvariant
173 179 class dirstatev2(requirementformatvariant):
174 180 name = b'dirstate-v2'
175 181 _requirement = requirements.DIRSTATE_V2_REQUIREMENT
176 182
177 183 default = False
178 184
179 185 description = _(
180 186 b'version 1 of the dirstate file format requires '
181 187 b'reading and parsing it all at once.\n'
182 188 b'Version 2 has a better structure,'
183 189 b'better information and lighter update mechanism'
184 190 )
185 191
186 192 upgrademessage = _(b'"hg status" will be faster')
187 193
188 194 touches_filelogs = False
189 195 touches_manifests = False
190 196 touches_changelog = False
191 197 touches_requirements = True
192 198 touches_dirstate = True
193 199
194 200
195 201 @registerformatvariant
196 202 class dotencode(requirementformatvariant):
197 203 name = b'dotencode'
198 204
199 205 _requirement = requirements.DOTENCODE_REQUIREMENT
200 206
201 207 default = True
202 208
203 209 description = _(
204 210 b'storage of filenames beginning with a period or '
205 211 b'space may not work correctly'
206 212 )
207 213
208 214 upgrademessage = _(
209 215 b'repository will be better able to store files '
210 216 b'beginning with a space or period'
211 217 )
212 218
213 219
214 220 @registerformatvariant
215 221 class generaldelta(requirementformatvariant):
216 222 name = b'generaldelta'
217 223
218 224 _requirement = requirements.GENERALDELTA_REQUIREMENT
219 225
220 226 default = True
221 227
222 228 description = _(
223 229 b'deltas within internal storage are unable to '
224 230 b'choose optimal revisions; repository is larger and '
225 231 b'slower than it could be; interaction with other '
226 232 b'repositories may require extra network and CPU '
227 233 b'resources, making "hg push" and "hg pull" slower'
228 234 )
229 235
230 236 upgrademessage = _(
231 237 b'repository storage will be able to create '
232 238 b'optimal deltas; new repository data will be '
233 239 b'smaller and read times should decrease; '
234 240 b'interacting with other repositories using this '
235 241 b'storage model should require less network and '
236 242 b'CPU resources, making "hg push" and "hg pull" '
237 243 b'faster'
238 244 )
239 245
240 246
241 247 @registerformatvariant
242 248 class sharesafe(requirementformatvariant):
243 249 name = b'share-safe'
244 250 _requirement = requirements.SHARESAFE_REQUIREMENT
245 251
246 252 default = True
247 253
248 254 description = _(
249 255 b'old shared repositories do not share source repository '
250 256 b'requirements and config. This leads to various problems '
251 257 b'when the source repository format is upgraded or some new '
252 258 b'extensions are enabled.'
253 259 )
254 260
255 261 upgrademessage = _(
256 262 b'Upgrades a repository to share-safe format so that future '
257 263 b'shares of this repository share its requirements and configs.'
258 264 )
259 265
260 266 postdowngrademessage = _(
261 267 b'repository downgraded to not use share safe mode, '
262 268 b'existing shares will not work and needs to'
263 269 b' be reshared.'
264 270 )
265 271
266 272 postupgrademessage = _(
267 273 b'repository upgraded to share safe mode, existing'
268 274 b' shares will still work in old non-safe mode. '
269 275 b'Re-share existing shares to use them in safe mode'
270 276 b' New shares will be created in safe mode.'
271 277 )
272 278
273 279 # upgrade only needs to change the requirements
274 280 touches_filelogs = False
275 281 touches_manifests = False
276 282 touches_changelog = False
277 283 touches_requirements = True
278 284
279 285
280 286 @registerformatvariant
281 287 class sparserevlog(requirementformatvariant):
282 288 name = b'sparserevlog'
283 289
284 290 _requirement = requirements.SPARSEREVLOG_REQUIREMENT
285 291
286 292 default = True
287 293
288 294 description = _(
289 295 b'in order to limit disk reading and memory usage on older '
290 296 b'version, the span of a delta chain from its root to its '
291 297 b'end is limited, whatever the relevant data in this span. '
292 298 b'This can severly limit Mercurial ability to build good '
293 299 b'chain of delta resulting is much more storage space being '
294 300 b'taken and limit reusability of on disk delta during '
295 301 b'exchange.'
296 302 )
297 303
298 304 upgrademessage = _(
299 305 b'Revlog supports delta chain with more unused data '
300 306 b'between payload. These gaps will be skipped at read '
301 307 b'time. This allows for better delta chains, making a '
302 308 b'better compression and faster exchange with server.'
303 309 )
304 310
305 311
306 312 @registerformatvariant
307 313 class persistentnodemap(requirementformatvariant):
308 314 name = b'persistent-nodemap'
309 315
310 316 _requirement = requirements.NODEMAP_REQUIREMENT
311 317
312 318 default = False
313 319
314 320 description = _(
315 321 b'persist the node -> rev mapping on disk to speedup lookup'
316 322 )
317 323
318 324 upgrademessage = _(b'Speedup revision lookup by node id.')
319 325
320 326
321 327 @registerformatvariant
322 328 class copiessdc(requirementformatvariant):
323 329 name = b'copies-sdc'
324 330
325 331 _requirement = requirements.COPIESSDC_REQUIREMENT
326 332
327 333 default = False
328 334
329 335 description = _(b'Stores copies information alongside changesets.')
330 336
331 337 upgrademessage = _(
332 338 b'Allows to use more efficient algorithm to deal with ' b'copy tracing.'
333 339 )
334 340
335 341
336 342 @registerformatvariant
337 343 class revlogv2(requirementformatvariant):
338 344 name = b'revlog-v2'
339 345 _requirement = requirements.REVLOGV2_REQUIREMENT
340 346 default = False
341 347 description = _(b'Version 2 of the revlog.')
342 348 upgrademessage = _(b'very experimental')
343 349
344 350
345 351 @registerformatvariant
346 352 class changelogv2(requirementformatvariant):
347 353 name = b'changelog-v2'
348 354 _requirement = requirements.CHANGELOGV2_REQUIREMENT
349 355 default = False
350 356 description = _(b'An iteration of the revlog focussed on changelog needs.')
351 357 upgrademessage = _(b'quite experimental')
352 358
353 359
354 360 @registerformatvariant
355 361 class removecldeltachain(formatvariant):
356 362 name = b'plain-cl-delta'
357 363
358 364 default = True
359 365
360 366 description = _(
361 367 b'changelog storage is using deltas instead of '
362 368 b'raw entries; changelog reading and any '
363 369 b'operation relying on changelog data are slower '
364 370 b'than they could be'
365 371 )
366 372
367 373 upgrademessage = _(
368 374 b'changelog storage will be reformated to '
369 375 b'store raw entries; changelog reading will be '
370 376 b'faster; changelog size may be reduced'
371 377 )
372 378
373 379 @staticmethod
374 380 def fromrepo(repo):
375 381 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
376 382 # changelogs with deltas.
377 383 cl = repo.changelog
378 384 chainbase = cl.chainbase
379 385 return all(rev == chainbase(rev) for rev in cl)
380 386
381 387 @staticmethod
382 388 def fromconfig(repo):
383 389 return True
384 390
385 391
386 392 _has_zstd = (
387 393 b'zstd' in util.compengines
388 394 and util.compengines[b'zstd'].available()
389 395 and util.compengines[b'zstd'].revlogheader()
390 396 )
391 397
392 398
393 399 @registerformatvariant
394 400 class compressionengine(formatvariant):
395 401 name = b'compression'
396 402
397 403 if _has_zstd:
398 404 default = b'zstd'
399 405 else:
400 406 default = b'zlib'
401 407
402 408 description = _(
403 409 b'Compresion algorithm used to compress data. '
404 410 b'Some engine are faster than other'
405 411 )
406 412
407 413 upgrademessage = _(
408 414 b'revlog content will be recompressed with the new algorithm.'
409 415 )
410 416
411 417 @classmethod
412 418 def fromrepo(cls, repo):
413 419 # we allow multiple compression engine requirement to co-exist because
414 420 # strickly speaking, revlog seems to support mixed compression style.
415 421 #
416 422 # The compression used for new entries will be "the last one"
417 423 compression = b'zlib'
418 424 for req in repo.requirements:
419 425 prefix = req.startswith
420 426 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
421 427 compression = req.split(b'-', 2)[2]
422 428 return compression
423 429
424 430 @classmethod
425 431 def fromconfig(cls, repo):
426 432 compengines = repo.ui.configlist(b'format', b'revlog-compression')
427 433 # return the first valid value as the selection code would do
428 434 for comp in compengines:
429 435 if comp in util.compengines:
430 436 e = util.compengines[comp]
431 437 if e.available() and e.revlogheader():
432 438 return comp
433 439
434 440 # no valide compression found lets display it all for clarity
435 441 return b','.join(compengines)
436 442
437 443
438 444 @registerformatvariant
439 445 class compressionlevel(formatvariant):
440 446 name = b'compression-level'
441 447 default = b'default'
442 448
443 449 description = _(b'compression level')
444 450
445 451 upgrademessage = _(b'revlog content will be recompressed')
446 452
447 453 @classmethod
448 454 def fromrepo(cls, repo):
449 455 comp = compressionengine.fromrepo(repo)
450 456 level = None
451 457 if comp == b'zlib':
452 458 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
453 459 elif comp == b'zstd':
454 460 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
455 461 if level is None:
456 462 return b'default'
457 463 return bytes(level)
458 464
459 465 @classmethod
460 466 def fromconfig(cls, repo):
461 467 comp = compressionengine.fromconfig(repo)
462 468 level = None
463 469 if comp == b'zlib':
464 470 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
465 471 elif comp == b'zstd':
466 472 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
467 473 if level is None:
468 474 return b'default'
469 475 return bytes(level)
470 476
471 477
472 478 def find_format_upgrades(repo):
473 479 """returns a list of format upgrades which can be perform on the repo"""
474 480 upgrades = []
475 481
476 482 # We could detect lack of revlogv1 and store here, but they were added
477 483 # in 0.9.2 and we don't support upgrading repos without these
478 484 # requirements, so let's not bother.
479 485
480 486 for fv in allformatvariant:
481 487 if not fv.fromrepo(repo):
482 488 upgrades.append(fv)
483 489
484 490 return upgrades
485 491
486 492
487 493 def find_format_downgrades(repo):
488 494 """returns a list of format downgrades which will be performed on the repo
489 495 because of disabled config option for them"""
490 496
491 497 downgrades = []
492 498
493 499 for fv in allformatvariant:
494 500 if fv.name == b'compression':
495 501 # If there is a compression change between repository
496 502 # and config, destination repository compression will change
497 503 # and current compression will be removed.
498 504 if fv.fromrepo(repo) != fv.fromconfig(repo):
499 505 downgrades.append(fv)
500 506 continue
501 507 # format variant exist in repo but does not exist in new repository
502 508 # config
503 509 if fv.fromrepo(repo) and not fv.fromconfig(repo):
504 510 downgrades.append(fv)
505 511
506 512 return downgrades
507 513
508 514
509 515 ALL_OPTIMISATIONS = []
510 516
511 517
512 518 def register_optimization(obj):
513 519 ALL_OPTIMISATIONS.append(obj)
514 520 return obj
515 521
516 522
517 523 class optimization(improvement):
518 524 """an improvement subclass dedicated to optimizations"""
519 525
520 526 type = OPTIMISATION
521 527
522 528
523 529 @register_optimization
524 530 class redeltaparents(optimization):
525 531 name = b're-delta-parent'
526 532
527 533 type = OPTIMISATION
528 534
529 535 description = _(
530 536 b'deltas within internal storage will be recalculated to '
531 537 b'choose an optimal base revision where this was not '
532 538 b'already done; the size of the repository may shrink and '
533 539 b'various operations may become faster; the first time '
534 540 b'this optimization is performed could slow down upgrade '
535 541 b'execution considerably; subsequent invocations should '
536 542 b'not run noticeably slower'
537 543 )
538 544
539 545 upgrademessage = _(
540 546 b'deltas within internal storage will choose a new '
541 547 b'base revision if needed'
542 548 )
543 549
544 550
545 551 @register_optimization
546 552 class redeltamultibase(optimization):
547 553 name = b're-delta-multibase'
548 554
549 555 type = OPTIMISATION
550 556
551 557 description = _(
552 558 b'deltas within internal storage will be recalculated '
553 559 b'against multiple base revision and the smallest '
554 560 b'difference will be used; the size of the repository may '
555 561 b'shrink significantly when there are many merges; this '
556 562 b'optimization will slow down execution in proportion to '
557 563 b'the number of merges in the repository and the amount '
558 564 b'of files in the repository; this slow down should not '
559 565 b'be significant unless there are tens of thousands of '
560 566 b'files and thousands of merges'
561 567 )
562 568
563 569 upgrademessage = _(
564 570 b'deltas within internal storage will choose an '
565 571 b'optimal delta by computing deltas against multiple '
566 572 b'parents; may slow down execution time '
567 573 b'significantly'
568 574 )
569 575
570 576
571 577 @register_optimization
572 578 class redeltaall(optimization):
573 579 name = b're-delta-all'
574 580
575 581 type = OPTIMISATION
576 582
577 583 description = _(
578 584 b'deltas within internal storage will always be '
579 585 b'recalculated without reusing prior deltas; this will '
580 586 b'likely make execution run several times slower; this '
581 587 b'optimization is typically not needed'
582 588 )
583 589
584 590 upgrademessage = _(
585 591 b'deltas within internal storage will be fully '
586 592 b'recomputed; this will likely drastically slow down '
587 593 b'execution time'
588 594 )
589 595
590 596
591 597 @register_optimization
592 598 class redeltafulladd(optimization):
593 599 name = b're-delta-fulladd'
594 600
595 601 type = OPTIMISATION
596 602
597 603 description = _(
598 604 b'every revision will be re-added as if it was new '
599 605 b'content. It will go through the full storage '
600 606 b'mechanism giving extensions a chance to process it '
601 607 b'(eg. lfs). This is similar to "re-delta-all" but even '
602 608 b'slower since more logic is involved.'
603 609 )
604 610
605 611 upgrademessage = _(
606 612 b'each revision will be added as new content to the '
607 613 b'internal storage; this will likely drastically slow '
608 614 b'down execution time, but some extensions might need '
609 615 b'it'
610 616 )
611 617
612 618
613 619 def findoptimizations(repo):
614 620 """Determine optimisation that could be used during upgrade"""
615 621 # These are unconditionally added. There is logic later that figures out
616 622 # which ones to apply.
617 623 return list(ALL_OPTIMISATIONS)
618 624
619 625
620 626 def determine_upgrade_actions(
621 627 repo, format_upgrades, optimizations, sourcereqs, destreqs
622 628 ):
623 629 """Determine upgrade actions that will be performed.
624 630
625 631 Given a list of improvements as returned by ``find_format_upgrades`` and
626 632 ``findoptimizations``, determine the list of upgrade actions that
627 633 will be performed.
628 634
629 635 The role of this function is to filter improvements if needed, apply
630 636 recommended optimizations from the improvements list that make sense,
631 637 etc.
632 638
633 639 Returns a list of action names.
634 640 """
635 641 newactions = []
636 642
637 643 for d in format_upgrades:
638 644 if util.safehasattr(d, '_requirement'):
639 645 name = d._requirement
640 646 else:
641 647 name = None
642 648
643 649 # If the action is a requirement that doesn't show up in the
644 650 # destination requirements, prune the action.
645 651 if name is not None and name not in destreqs:
646 652 continue
647 653
648 654 newactions.append(d)
649 655
650 656 newactions.extend(o for o in sorted(optimizations) if o not in newactions)
651 657
652 658 # FUTURE consider adding some optimizations here for certain transitions.
653 659 # e.g. adding generaldelta could schedule parent redeltas.
654 660
655 661 return newactions
656 662
657 663
658 664 class UpgradeOperation(object):
659 665 """represent the work to be done during an upgrade"""
660 666
661 667 def __init__(
662 668 self,
663 669 ui,
664 670 new_requirements,
665 671 current_requirements,
666 672 upgrade_actions,
667 673 removed_actions,
668 674 revlogs_to_process,
669 675 backup_store,
670 676 ):
671 677 self.ui = ui
672 678 self.new_requirements = new_requirements
673 679 self.current_requirements = current_requirements
674 680 # list of upgrade actions the operation will perform
675 681 self.upgrade_actions = upgrade_actions
676 682 self.removed_actions = removed_actions
677 683 self.revlogs_to_process = revlogs_to_process
678 684 # requirements which will be added by the operation
679 685 self._added_requirements = (
680 686 self.new_requirements - self.current_requirements
681 687 )
682 688 # requirements which will be removed by the operation
683 689 self._removed_requirements = (
684 690 self.current_requirements - self.new_requirements
685 691 )
686 692 # requirements which will be preserved by the operation
687 693 self._preserved_requirements = (
688 694 self.current_requirements & self.new_requirements
689 695 )
690 696 # optimizations which are not used and it's recommended that they
691 697 # should use them
692 698 all_optimizations = findoptimizations(None)
693 699 self.unused_optimizations = [
694 700 i for i in all_optimizations if i not in self.upgrade_actions
695 701 ]
696 702
697 703 # delta reuse mode of this upgrade operation
698 704 upgrade_actions_names = self.upgrade_actions_names
699 705 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS
700 706 if b're-delta-all' in upgrade_actions_names:
701 707 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER
702 708 elif b're-delta-parent' in upgrade_actions_names:
703 709 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
704 710 elif b're-delta-multibase' in upgrade_actions_names:
705 711 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
706 712 elif b're-delta-fulladd' in upgrade_actions_names:
707 713 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD
708 714
709 715 # should this operation force re-delta of both parents
710 716 self.force_re_delta_both_parents = (
711 717 b're-delta-multibase' in upgrade_actions_names
712 718 )
713 719
714 720 # should this operation create a backup of the store
715 721 self.backup_store = backup_store
716 722
717 723 @property
718 724 def upgrade_actions_names(self):
719 725 return set([a.name for a in self.upgrade_actions])
720 726
721 727 @property
722 728 def requirements_only(self):
723 729 # does the operation only touches repository requirement
724 730 return (
725 731 self.touches_requirements
726 732 and not self.touches_filelogs
727 733 and not self.touches_manifests
728 734 and not self.touches_changelog
729 735 and not self.touches_dirstate
730 736 )
731 737
732 738 @property
733 739 def touches_filelogs(self):
734 740 for a in self.upgrade_actions:
735 741 # in optimisations, we re-process the revlogs again
736 742 if a.type == OPTIMISATION:
737 743 return True
738 744 elif a.touches_filelogs:
739 745 return True
740 746 for a in self.removed_actions:
741 747 if a.touches_filelogs:
742 748 return True
743 749 return False
744 750
745 751 @property
746 752 def touches_manifests(self):
747 753 for a in self.upgrade_actions:
748 754 # in optimisations, we re-process the revlogs again
749 755 if a.type == OPTIMISATION:
750 756 return True
751 757 elif a.touches_manifests:
752 758 return True
753 759 for a in self.removed_actions:
754 760 if a.touches_manifests:
755 761 return True
756 762 return False
757 763
758 764 @property
759 765 def touches_changelog(self):
760 766 for a in self.upgrade_actions:
761 767 # in optimisations, we re-process the revlogs again
762 768 if a.type == OPTIMISATION:
763 769 return True
764 770 elif a.touches_changelog:
765 771 return True
766 772 for a in self.removed_actions:
767 773 if a.touches_changelog:
768 774 return True
769 775 return False
770 776
771 777 @property
772 778 def touches_requirements(self):
773 779 for a in self.upgrade_actions:
774 780 # optimisations are used to re-process revlogs and does not result
775 781 # in a requirement being added or removed
776 782 if a.type == OPTIMISATION:
777 783 pass
778 784 elif a.touches_requirements:
779 785 return True
780 786 for a in self.removed_actions:
781 787 if a.touches_requirements:
782 788 return True
783 789
784 790 @property
785 791 def touches_dirstate(self):
786 792 for a in self.upgrade_actions:
787 793 # revlog optimisations do not affect the dirstate
788 794 if a.type == OPTIMISATION:
789 795 pass
790 796 elif a.touches_dirstate:
791 797 return True
792 798 for a in self.removed_actions:
793 799 if a.touches_dirstate:
794 800 return True
795 801
796 802 return False
797 803
798 804 def _write_labeled(self, l, label):
799 805 """
800 806 Utility function to aid writing of a list under one label
801 807 """
802 808 first = True
803 809 for r in sorted(l):
804 810 if not first:
805 811 self.ui.write(b', ')
806 812 self.ui.write(r, label=label)
807 813 first = False
808 814
809 815 def print_requirements(self):
810 816 self.ui.write(_(b'requirements\n'))
811 817 self.ui.write(_(b' preserved: '))
812 818 self._write_labeled(
813 819 self._preserved_requirements, "upgrade-repo.requirement.preserved"
814 820 )
815 821 self.ui.write((b'\n'))
816 822 if self._removed_requirements:
817 823 self.ui.write(_(b' removed: '))
818 824 self._write_labeled(
819 825 self._removed_requirements, "upgrade-repo.requirement.removed"
820 826 )
821 827 self.ui.write((b'\n'))
822 828 if self._added_requirements:
823 829 self.ui.write(_(b' added: '))
824 830 self._write_labeled(
825 831 self._added_requirements, "upgrade-repo.requirement.added"
826 832 )
827 833 self.ui.write((b'\n'))
828 834 self.ui.write(b'\n')
829 835
830 836 def print_optimisations(self):
831 837 optimisations = [
832 838 a for a in self.upgrade_actions if a.type == OPTIMISATION
833 839 ]
834 840 optimisations.sort(key=lambda a: a.name)
835 841 if optimisations:
836 842 self.ui.write(_(b'optimisations: '))
837 843 self._write_labeled(
838 844 [a.name for a in optimisations],
839 845 "upgrade-repo.optimisation.performed",
840 846 )
841 847 self.ui.write(b'\n\n')
842 848
843 849 def print_upgrade_actions(self):
844 850 for a in self.upgrade_actions:
845 851 self.ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
846 852
847 853 def print_affected_revlogs(self):
848 854 if not self.revlogs_to_process:
849 855 self.ui.write((b'no revlogs to process\n'))
850 856 else:
851 857 self.ui.write((b'processed revlogs:\n'))
852 858 for r in sorted(self.revlogs_to_process):
853 859 self.ui.write((b' - %s\n' % r))
854 860 self.ui.write((b'\n'))
855 861
856 862 def print_unused_optimizations(self):
857 863 for i in self.unused_optimizations:
858 864 self.ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
859 865
860 866 def has_upgrade_action(self, name):
861 867 """Check whether the upgrade operation will perform this action"""
862 868 return name in self._upgrade_actions_names
863 869
864 870 def print_post_op_messages(self):
865 871 """print post upgrade operation warning messages"""
866 872 for a in self.upgrade_actions:
867 873 if a.postupgrademessage is not None:
868 874 self.ui.warn(b'%s\n' % a.postupgrademessage)
869 875 for a in self.removed_actions:
870 876 if a.postdowngrademessage is not None:
871 877 self.ui.warn(b'%s\n' % a.postdowngrademessage)
872 878
873 879
874 880 ### Code checking if a repository can got through the upgrade process at all. #
875 881
876 882
877 883 def requiredsourcerequirements(repo):
878 884 """Obtain requirements required to be present to upgrade a repo.
879 885
880 886 An upgrade will not be allowed if the repository doesn't have the
881 887 requirements returned by this function.
882 888 """
883 889 return {
884 890 # Introduced in Mercurial 0.9.2.
885 891 requirements.STORE_REQUIREMENT,
886 892 }
887 893
888 894
889 895 def blocksourcerequirements(repo):
890 896 """Obtain requirements that will prevent an upgrade from occurring.
891 897
892 898 An upgrade cannot be performed if the source repository contains a
893 899 requirements in the returned set.
894 900 """
895 901 return {
896 902 # The upgrade code does not yet support these experimental features.
897 903 # This is an artificial limitation.
898 904 requirements.TREEMANIFEST_REQUIREMENT,
899 905 # This was a precursor to generaldelta and was never enabled by default.
900 906 # It should (hopefully) not exist in the wild.
901 907 b'parentdelta',
902 # Upgrade should operate on the actual store, not the shared link.
903 requirements.SHARED_REQUIREMENT,
904 908 }
905 909
906 910
907 911 def check_revlog_version(reqs):
908 912 """Check that the requirements contain at least one Revlog version"""
909 913 all_revlogs = {
910 914 requirements.REVLOGV1_REQUIREMENT,
911 915 requirements.REVLOGV2_REQUIREMENT,
912 916 }
913 917 if not all_revlogs.intersection(reqs):
914 918 msg = _(b'cannot upgrade repository; missing a revlog version')
915 919 raise error.Abort(msg)
916 920
917 921
918 922 def check_source_requirements(repo):
919 923 """Ensure that no existing requirements prevent the repository upgrade"""
920 924
921 925 check_revlog_version(repo.requirements)
922 926 required = requiredsourcerequirements(repo)
923 927 missingreqs = required - repo.requirements
924 928 if missingreqs:
925 929 msg = _(b'cannot upgrade repository; requirement missing: %s')
926 930 missingreqs = b', '.join(sorted(missingreqs))
927 931 raise error.Abort(msg % missingreqs)
928 932
929 933 blocking = blocksourcerequirements(repo)
930 934 blockingreqs = blocking & repo.requirements
931 935 if blockingreqs:
932 936 m = _(b'cannot upgrade repository; unsupported source requirement: %s')
933 937 blockingreqs = b', '.join(sorted(blockingreqs))
934 938 raise error.Abort(m % blockingreqs)
939 # Upgrade should operate on the actual store, not the shared link.
940
941 bad_share = (
942 requirements.SHARED_REQUIREMENT in repo.requirements
943 and requirements.SHARESAFE_REQUIREMENT not in repo.requirements
944 )
945 if bad_share:
946 m = _(b'cannot upgrade repository; share repository without share-safe')
947 h = _(b'check :hg:`help config.format.use-share-safe`')
948 raise error.Abort(m, hint=h)
935 949
936 950
937 951 ### Verify the validity of the planned requirement changes ####################
938 952
939 953
940 954 def supportremovedrequirements(repo):
941 955 """Obtain requirements that can be removed during an upgrade.
942 956
943 957 If an upgrade were to create a repository that dropped a requirement,
944 958 the dropped requirement must appear in the returned set for the upgrade
945 959 to be allowed.
946 960 """
947 961 supported = {
948 962 requirements.SPARSEREVLOG_REQUIREMENT,
949 963 requirements.COPIESSDC_REQUIREMENT,
950 964 requirements.NODEMAP_REQUIREMENT,
951 965 requirements.SHARESAFE_REQUIREMENT,
952 966 requirements.REVLOGV2_REQUIREMENT,
953 967 requirements.CHANGELOGV2_REQUIREMENT,
954 968 requirements.REVLOGV1_REQUIREMENT,
955 969 requirements.DIRSTATE_V2_REQUIREMENT,
956 970 }
957 971 for name in compression.compengines:
958 972 engine = compression.compengines[name]
959 973 if engine.available() and engine.revlogheader():
960 974 supported.add(b'exp-compression-%s' % name)
961 975 if engine.name() == b'zstd':
962 976 supported.add(b'revlog-compression-zstd')
963 977 return supported
964 978
965 979
966 980 def supporteddestrequirements(repo):
967 981 """Obtain requirements that upgrade supports in the destination.
968 982
969 983 If the result of the upgrade would create requirements not in this set,
970 984 the upgrade is disallowed.
971 985
972 986 Extensions should monkeypatch this to add their custom requirements.
973 987 """
974 988 supported = {
989 requirements.CHANGELOGV2_REQUIREMENT,
990 requirements.COPIESSDC_REQUIREMENT,
991 requirements.DIRSTATE_V2_REQUIREMENT,
975 992 requirements.DOTENCODE_REQUIREMENT,
976 993 requirements.FNCACHE_REQUIREMENT,
977 994 requirements.GENERALDELTA_REQUIREMENT,
995 requirements.NODEMAP_REQUIREMENT,
978 996 requirements.REVLOGV1_REQUIREMENT, # allowed in case of downgrade
979 requirements.STORE_REQUIREMENT,
997 requirements.REVLOGV2_REQUIREMENT,
998 requirements.SHARED_REQUIREMENT,
999 requirements.SHARESAFE_REQUIREMENT,
980 1000 requirements.SPARSEREVLOG_REQUIREMENT,
981 requirements.COPIESSDC_REQUIREMENT,
982 requirements.NODEMAP_REQUIREMENT,
983 requirements.SHARESAFE_REQUIREMENT,
984 requirements.REVLOGV2_REQUIREMENT,
985 requirements.CHANGELOGV2_REQUIREMENT,
986 requirements.DIRSTATE_V2_REQUIREMENT,
1001 requirements.STORE_REQUIREMENT,
987 1002 }
988 1003 for name in compression.compengines:
989 1004 engine = compression.compengines[name]
990 1005 if engine.available() and engine.revlogheader():
991 1006 supported.add(b'exp-compression-%s' % name)
992 1007 if engine.name() == b'zstd':
993 1008 supported.add(b'revlog-compression-zstd')
994 1009 return supported
995 1010
996 1011
997 1012 def allowednewrequirements(repo):
998 1013 """Obtain requirements that can be added to a repository during upgrade.
999 1014
1000 1015 This is used to disallow proposed requirements from being added when
1001 1016 they weren't present before.
1002 1017
1003 1018 We use a list of allowed requirement additions instead of a list of known
1004 1019 bad additions because the whitelist approach is safer and will prevent
1005 1020 future, unknown requirements from accidentally being added.
1006 1021 """
1007 1022 supported = {
1008 1023 requirements.DOTENCODE_REQUIREMENT,
1009 1024 requirements.FNCACHE_REQUIREMENT,
1010 1025 requirements.GENERALDELTA_REQUIREMENT,
1011 1026 requirements.SPARSEREVLOG_REQUIREMENT,
1012 1027 requirements.COPIESSDC_REQUIREMENT,
1013 1028 requirements.NODEMAP_REQUIREMENT,
1014 1029 requirements.SHARESAFE_REQUIREMENT,
1015 1030 requirements.REVLOGV1_REQUIREMENT,
1016 1031 requirements.REVLOGV2_REQUIREMENT,
1017 1032 requirements.CHANGELOGV2_REQUIREMENT,
1018 1033 requirements.DIRSTATE_V2_REQUIREMENT,
1019 1034 }
1020 1035 for name in compression.compengines:
1021 1036 engine = compression.compengines[name]
1022 1037 if engine.available() and engine.revlogheader():
1023 1038 supported.add(b'exp-compression-%s' % name)
1024 1039 if engine.name() == b'zstd':
1025 1040 supported.add(b'revlog-compression-zstd')
1026 1041 return supported
1027 1042
1028 1043
1029 1044 def check_requirements_changes(repo, new_reqs):
1030 1045 old_reqs = repo.requirements
1031 1046 check_revlog_version(repo.requirements)
1032 1047 support_removal = supportremovedrequirements(repo)
1033 1048 no_remove_reqs = old_reqs - new_reqs - support_removal
1034 1049 if no_remove_reqs:
1035 1050 msg = _(b'cannot upgrade repository; requirement would be removed: %s')
1036 1051 no_remove_reqs = b', '.join(sorted(no_remove_reqs))
1037 1052 raise error.Abort(msg % no_remove_reqs)
1038 1053
1039 1054 support_addition = allowednewrequirements(repo)
1040 1055 no_add_reqs = new_reqs - old_reqs - support_addition
1041 1056 if no_add_reqs:
1042 1057 m = _(b'cannot upgrade repository; do not support adding requirement: ')
1043 1058 no_add_reqs = b', '.join(sorted(no_add_reqs))
1044 1059 raise error.Abort(m + no_add_reqs)
1045 1060
1046 1061 supported = supporteddestrequirements(repo)
1047 1062 unsupported_reqs = new_reqs - supported
1048 1063 if unsupported_reqs:
1049 1064 msg = _(
1050 1065 b'cannot upgrade repository; do not support destination '
1051 1066 b'requirement: %s'
1052 1067 )
1053 1068 unsupported_reqs = b', '.join(sorted(unsupported_reqs))
1054 1069 raise error.Abort(msg % unsupported_reqs)
@@ -1,604 +1,605 b''
1 1 setup
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > share =
6 6 > [format]
7 7 > use-share-safe = True
8 8 > [storage]
9 9 > revlog.persistent-nodemap.slow-path=allow
10 10 > # enforce zlib to ensure we can upgrade to zstd later
11 11 > [format]
12 12 > revlog-compression=zlib
13 13 > # we want to be able to enable it later
14 14 > use-persistent-nodemap=no
15 15 > EOF
16 16
17 17 prepare source repo
18 18
19 19 $ hg init source
20 20 $ cd source
21 21 $ cat .hg/requires
22 22 dirstate-v2 (dirstate-v2 !)
23 23 share-safe
24 24 $ cat .hg/store/requires
25 25 dotencode
26 26 fncache
27 27 generaldelta
28 28 revlogv1
29 29 sparserevlog
30 30 store
31 31 $ hg debugrequirements
32 32 dotencode
33 33 dirstate-v2 (dirstate-v2 !)
34 34 fncache
35 35 generaldelta
36 36 revlogv1
37 37 share-safe
38 38 sparserevlog
39 39 store
40 40
41 41 $ echo a > a
42 42 $ hg ci -Aqm "added a"
43 43 $ echo b > b
44 44 $ hg ci -Aqm "added b"
45 45
46 46 $ HGEDITOR=cat hg config --shared
47 47 abort: repository is not shared; can't use --shared
48 48 [10]
49 49 $ cd ..
50 50
51 51 Create a shared repo and check the requirements are shared and read correctly
52 52 $ hg share source shared1
53 53 updating working directory
54 54 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 55 $ cd shared1
56 56 $ cat .hg/requires
57 57 dirstate-v2 (dirstate-v2 !)
58 58 share-safe
59 59 shared
60 60
61 61 $ hg debugrequirements -R ../source
62 62 dotencode
63 63 dirstate-v2 (dirstate-v2 !)
64 64 fncache
65 65 generaldelta
66 66 revlogv1
67 67 share-safe
68 68 sparserevlog
69 69 store
70 70
71 71 $ hg debugrequirements
72 72 dotencode
73 73 dirstate-v2 (dirstate-v2 !)
74 74 fncache
75 75 generaldelta
76 76 revlogv1
77 77 share-safe
78 78 shared
79 79 sparserevlog
80 80 store
81 81
82 82 $ echo c > c
83 83 $ hg ci -Aqm "added c"
84 84
85 85 Check that config of the source repository is also loaded
86 86
87 87 $ hg showconfig ui.curses
88 88 [1]
89 89
90 90 $ echo "[ui]" >> ../source/.hg/hgrc
91 91 $ echo "curses=true" >> ../source/.hg/hgrc
92 92
93 93 $ hg showconfig ui.curses
94 94 true
95 95
96 96 Test that extensions of source repository are also loaded
97 97
98 98 $ hg debugextensions
99 99 share
100 100 $ hg extdiff -p echo
101 101 hg: unknown command 'extdiff'
102 102 'extdiff' is provided by the following extension:
103 103
104 104 extdiff command to allow external programs to compare revisions
105 105
106 106 (use 'hg help extensions' for information on enabling extensions)
107 107 [10]
108 108
109 109 $ echo "[extensions]" >> ../source/.hg/hgrc
110 110 $ echo "extdiff=" >> ../source/.hg/hgrc
111 111
112 112 $ hg debugextensions -R ../source
113 113 extdiff
114 114 share
115 115 $ hg extdiff -R ../source -p echo
116 116
117 117 BROKEN: the command below will not work if config of shared source is not loaded
118 118 on dispatch but debugextensions says that extension
119 119 is loaded
120 120 $ hg debugextensions
121 121 extdiff
122 122 share
123 123
124 124 $ hg extdiff -p echo
125 125
126 126 However, local .hg/hgrc should override the config set by share source
127 127
128 128 $ echo "[ui]" >> .hg/hgrc
129 129 $ echo "curses=false" >> .hg/hgrc
130 130
131 131 $ hg showconfig ui.curses
132 132 false
133 133
134 134 $ HGEDITOR=cat hg config --shared
135 135 [ui]
136 136 curses=true
137 137 [extensions]
138 138 extdiff=
139 139
140 140 $ HGEDITOR=cat hg config --local
141 141 [ui]
142 142 curses=false
143 143
144 144 Testing that hooks set in source repository also runs in shared repo
145 145
146 146 $ cd ../source
147 147 $ cat <<EOF >> .hg/hgrc
148 148 > [extensions]
149 149 > hooklib=
150 150 > [hooks]
151 151 > pretxnchangegroup.reject_merge_commits = \
152 152 > python:hgext.hooklib.reject_merge_commits.hook
153 153 > EOF
154 154
155 155 $ cd ..
156 156 $ hg clone source cloned
157 157 updating to branch default
158 158 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 159 $ cd cloned
160 160 $ hg up 0
161 161 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
162 162 $ echo bar > bar
163 163 $ hg ci -Aqm "added bar"
164 164 $ hg merge
165 165 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 166 (branch merge, don't forget to commit)
167 167 $ hg ci -m "merge commit"
168 168
169 169 $ hg push ../source
170 170 pushing to ../source
171 171 searching for changes
172 172 adding changesets
173 173 adding manifests
174 174 adding file changes
175 175 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
176 176 transaction abort!
177 177 rollback completed
178 178 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
179 179 [255]
180 180
181 181 $ hg push ../shared1
182 182 pushing to ../shared1
183 183 searching for changes
184 184 adding changesets
185 185 adding manifests
186 186 adding file changes
187 187 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
188 188 transaction abort!
189 189 rollback completed
190 190 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
191 191 [255]
192 192
193 193 Test that if share source config is untrusted, we dont read it
194 194
195 195 $ cd ../shared1
196 196
197 197 $ cat << EOF > $TESTTMP/untrusted.py
198 198 > from mercurial import scmutil, util
199 199 > def uisetup(ui):
200 200 > class untrustedui(ui.__class__):
201 201 > def _trusted(self, fp, f):
202 202 > if util.normpath(fp.name).endswith(b'source/.hg/hgrc'):
203 203 > return False
204 204 > return super(untrustedui, self)._trusted(fp, f)
205 205 > ui.__class__ = untrustedui
206 206 > EOF
207 207
208 208 $ hg showconfig hooks
209 209 hooks.pretxnchangegroup.reject_merge_commits=python:hgext.hooklib.reject_merge_commits.hook
210 210
211 211 $ hg showconfig hooks --config extensions.untrusted=$TESTTMP/untrusted.py
212 212 [1]
213 213
214 214 Update the source repository format and check that shared repo works
215 215
216 216 $ cd ../source
217 217
218 218 Disable zstd related tests because its not present on pure version
219 219 #if zstd
220 220 $ echo "[format]" >> .hg/hgrc
221 221 $ echo "revlog-compression=zstd" >> .hg/hgrc
222 222
223 223 $ hg debugupgraderepo --run -q
224 224 upgrade will perform the following actions:
225 225
226 226 requirements
227 227 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-dirstate-v2 !)
228 228 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (dirstate-v2 !)
229 229 added: revlog-compression-zstd
230 230
231 231 processed revlogs:
232 232 - all-filelogs
233 233 - changelog
234 234 - manifest
235 235
236 236 $ hg log -r .
237 237 changeset: 1:5f6d8a4bf34a
238 238 user: test
239 239 date: Thu Jan 01 00:00:00 1970 +0000
240 240 summary: added b
241 241
242 242 #endif
243 243 $ echo "[format]" >> .hg/hgrc
244 244 $ echo "use-persistent-nodemap=True" >> .hg/hgrc
245 245
246 246 $ hg debugupgraderepo --run -q -R ../shared1
247 abort: cannot upgrade repository; unsupported source requirement: shared
247 abort: cannot use these actions on a share repository: persistent-nodemap
248 (upgrade the main repository directly)
248 249 [255]
249 250
250 251 $ hg debugupgraderepo --run -q
251 252 upgrade will perform the following actions:
252 253
253 254 requirements
254 255 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
255 256 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
256 257 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd dirstate-v2 !)
257 258 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
258 259 added: persistent-nodemap
259 260
260 261 processed revlogs:
261 262 - all-filelogs
262 263 - changelog
263 264 - manifest
264 265
265 266 $ hg log -r .
266 267 changeset: 1:5f6d8a4bf34a
267 268 user: test
268 269 date: Thu Jan 01 00:00:00 1970 +0000
269 270 summary: added b
270 271
271 272
272 273 Shared one should work
273 274 $ cd ../shared1
274 275 $ hg log -r .
275 276 changeset: 2:155349b645be
276 277 tag: tip
277 278 user: test
278 279 date: Thu Jan 01 00:00:00 1970 +0000
279 280 summary: added c
280 281
281 282
282 283 Testing that nonsharedrc is loaded for source and not shared
283 284
284 285 $ cd ../source
285 286 $ touch .hg/hgrc-not-shared
286 287 $ echo "[ui]" >> .hg/hgrc-not-shared
287 288 $ echo "traceback=true" >> .hg/hgrc-not-shared
288 289
289 290 $ hg showconfig ui.traceback
290 291 true
291 292
292 293 $ HGEDITOR=cat hg config --non-shared
293 294 [ui]
294 295 traceback=true
295 296
296 297 $ cd ../shared1
297 298 $ hg showconfig ui.traceback
298 299 [1]
299 300
300 301 Unsharing works
301 302
302 303 $ hg unshare
303 304
304 305 Test that source config is added to the shared one after unshare, and the config
305 306 of current repo is still respected over the config which came from source config
306 307 $ cd ../cloned
307 308 $ hg push ../shared1
308 309 pushing to ../shared1
309 310 searching for changes
310 311 adding changesets
311 312 adding manifests
312 313 adding file changes
313 314 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
314 315 transaction abort!
315 316 rollback completed
316 317 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
317 318 [255]
318 319 $ hg showconfig ui.curses -R ../shared1
319 320 false
320 321
321 322 $ cd ../
322 323
323 324 Test that upgrading using debugupgraderepo works
324 325 =================================================
325 326
326 327 $ hg init non-share-safe --config format.use-share-safe=false
327 328 $ cd non-share-safe
328 329 $ hg debugrequirements
329 330 dotencode
330 331 dirstate-v2 (dirstate-v2 !)
331 332 fncache
332 333 generaldelta
333 334 revlogv1
334 335 sparserevlog
335 336 store
336 337 $ echo foo > foo
337 338 $ hg ci -Aqm 'added foo'
338 339 $ echo bar > bar
339 340 $ hg ci -Aqm 'added bar'
340 341
341 342 Create a share before upgrading
342 343
343 344 $ cd ..
344 345 $ hg share non-share-safe nss-share
345 346 updating working directory
346 347 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 348 $ hg debugrequirements -R nss-share
348 349 dotencode
349 350 dirstate-v2 (dirstate-v2 !)
350 351 fncache
351 352 generaldelta
352 353 revlogv1
353 354 shared
354 355 sparserevlog
355 356 store
356 357 $ cd non-share-safe
357 358
358 359 Upgrade
359 360
360 361 $ hg debugupgraderepo -q
361 362 requirements
362 363 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-dirstate-v2 !)
363 364 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, sparserevlog, store (dirstate-v2 !)
364 365 added: share-safe
365 366
366 367 no revlogs to process
367 368
368 369 $ hg debugupgraderepo --run
369 370 upgrade will perform the following actions:
370 371
371 372 requirements
372 373 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-dirstate-v2 !)
373 374 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, sparserevlog, store (dirstate-v2 !)
374 375 added: share-safe
375 376
376 377 share-safe
377 378 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
378 379
379 380 no revlogs to process
380 381
381 382 beginning upgrade...
382 383 repository locked and read-only
383 384 creating temporary repository to stage upgraded data: $TESTTMP/non-share-safe/.hg/upgrade.* (glob)
384 385 (it is safe to interrupt this process any time before data migration completes)
385 386 upgrading repository requirements
386 387 removing temporary repository $TESTTMP/non-share-safe/.hg/upgrade.* (glob)
387 388 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
388 389
389 390 $ hg debugrequirements
390 391 dotencode
391 392 dirstate-v2 (dirstate-v2 !)
392 393 fncache
393 394 generaldelta
394 395 revlogv1
395 396 share-safe
396 397 sparserevlog
397 398 store
398 399
399 400 $ cat .hg/requires
400 401 dirstate-v2 (dirstate-v2 !)
401 402 share-safe
402 403
403 404 $ cat .hg/store/requires
404 405 dotencode
405 406 fncache
406 407 generaldelta
407 408 revlogv1
408 409 sparserevlog
409 410 store
410 411
411 412 $ hg log -GT "{node}: {desc}\n"
412 413 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
413 414 |
414 415 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
415 416
416 417
417 418 Make sure existing shares dont work with default config
418 419
419 420 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
420 421 abort: version mismatch: source uses share-safe functionality while the current share does not
421 422 (see `hg help config.format.use-share-safe` for more information)
422 423 [255]
423 424
424 425
425 426 Create a safe share from upgrade one
426 427
427 428 $ cd ..
428 429 $ hg share non-share-safe ss-share
429 430 updating working directory
430 431 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 432 $ cd ss-share
432 433 $ hg log -GT "{node}: {desc}\n"
433 434 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
434 435 |
435 436 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
436 437
437 438 $ cd ../non-share-safe
438 439
439 440 Test that downgrading works too
440 441
441 442 $ cat >> $HGRCPATH <<EOF
442 443 > [extensions]
443 444 > share =
444 445 > [format]
445 446 > use-share-safe = False
446 447 > EOF
447 448
448 449 $ hg debugupgraderepo -q
449 450 requirements
450 451 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-dirstate-v2 !)
451 452 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, sparserevlog, store (dirstate-v2 !)
452 453 removed: share-safe
453 454
454 455 no revlogs to process
455 456
456 457 $ hg debugupgraderepo --run
457 458 upgrade will perform the following actions:
458 459
459 460 requirements
460 461 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-dirstate-v2 !)
461 462 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, sparserevlog, store (dirstate-v2 !)
462 463 removed: share-safe
463 464
464 465 no revlogs to process
465 466
466 467 beginning upgrade...
467 468 repository locked and read-only
468 469 creating temporary repository to stage upgraded data: $TESTTMP/non-share-safe/.hg/upgrade.* (glob)
469 470 (it is safe to interrupt this process any time before data migration completes)
470 471 upgrading repository requirements
471 472 removing temporary repository $TESTTMP/non-share-safe/.hg/upgrade.* (glob)
472 473 repository downgraded to not use share safe mode, existing shares will not work and needs to be reshared.
473 474
474 475 $ hg debugrequirements
475 476 dotencode
476 477 dirstate-v2 (dirstate-v2 !)
477 478 fncache
478 479 generaldelta
479 480 revlogv1
480 481 sparserevlog
481 482 store
482 483
483 484 $ cat .hg/requires
484 485 dotencode
485 486 dirstate-v2 (dirstate-v2 !)
486 487 fncache
487 488 generaldelta
488 489 revlogv1
489 490 sparserevlog
490 491 store
491 492
492 493 $ test -f .hg/store/requires
493 494 [1]
494 495
495 496 $ hg log -GT "{node}: {desc}\n"
496 497 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
497 498 |
498 499 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
499 500
500 501
501 502 Make sure existing shares still works
502 503
503 504 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
504 505 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
505 506 |
506 507 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
507 508
508 509
509 510 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
510 511 abort: share source does not support share-safe requirement
511 512 (see `hg help config.format.use-share-safe` for more information)
512 513 [255]
513 514
514 515 Testing automatic downgrade of shares when config is set
515 516
516 517 $ touch ../ss-share/.hg/wlock
517 518 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
518 519 abort: failed to downgrade share, got error: Lock held
519 520 (see `hg help config.format.use-share-safe` for more information)
520 521 [255]
521 522 $ rm ../ss-share/.hg/wlock
522 523
523 524 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
524 525 repository downgraded to not use share-safe mode
525 526 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
526 527 |
527 528 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
528 529
529 530
530 531 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
531 532 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
532 533 |
533 534 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
534 535
535 536
536 537
537 538 Testing automatic upgrade of shares when config is set
538 539
539 540 $ hg debugupgraderepo -q --run --config format.use-share-safe=True
540 541 upgrade will perform the following actions:
541 542
542 543 requirements
543 544 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-dirstate-v2 !)
544 545 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlogv1, sparserevlog, store (dirstate-v2 !)
545 546 added: share-safe
546 547
547 548 no revlogs to process
548 549
549 550 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
550 551 $ hg debugrequirements
551 552 dotencode
552 553 dirstate-v2 (dirstate-v2 !)
553 554 fncache
554 555 generaldelta
555 556 revlogv1
556 557 share-safe
557 558 sparserevlog
558 559 store
559 560 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
560 561 abort: version mismatch: source uses share-safe functionality while the current share does not
561 562 (see `hg help config.format.use-share-safe` for more information)
562 563 [255]
563 564
564 565 Check that if lock is taken, upgrade fails but read operation are successful
565 566 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgra
566 567 abort: share-safe mismatch with source.
567 568 Unrecognized value 'upgra' of `share.safe-mismatch.source-safe` set.
568 569 (see `hg help config.format.use-share-safe` for more information)
569 570 [255]
570 571 $ touch ../nss-share/.hg/wlock
571 572 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow
572 573 failed to upgrade share, got error: Lock held
573 574 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
574 575 |
575 576 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
576 577
577 578
578 579 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow --config share.safe-mismatch.source-safe.warn=False
579 580 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
580 581 |
581 582 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
582 583
583 584
584 585 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
585 586 abort: failed to upgrade share, got error: Lock held
586 587 (see `hg help config.format.use-share-safe` for more information)
587 588 [255]
588 589
589 590 $ rm ../nss-share/.hg/wlock
590 591 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
591 592 repository upgraded to use share-safe mode
592 593 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
593 594 |
594 595 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
595 596
596 597
597 598 Test that unshare works
598 599
599 600 $ hg unshare -R ../nss-share
600 601 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
601 602 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
602 603 |
603 604 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
604 605
@@ -1,1822 +1,1824 b''
1 1 #require no-reposimplestore
2 2
3 3 $ cat >> $HGRCPATH << EOF
4 4 > [extensions]
5 5 > share =
6 6 > [format]
7 7 > # stabilize test accross variant
8 8 > revlog-compression=zlib
9 9 > EOF
10 10
11 11 store and revlogv1 are required in source
12 12
13 13 $ hg --config format.usestore=false init no-store
14 14 $ hg -R no-store debugupgraderepo
15 15 abort: cannot upgrade repository; requirement missing: store
16 16 [255]
17 17
18 18 $ hg init no-revlogv1
19 19 $ cat > no-revlogv1/.hg/requires << EOF
20 20 > dotencode
21 21 > fncache
22 22 > generaldelta
23 23 > store
24 24 > EOF
25 25
26 26 $ hg -R no-revlogv1 debugupgraderepo
27 27 abort: cannot upgrade repository; missing a revlog version
28 28 [255]
29 29
30 30 Cannot upgrade shared repositories
31 31
32 32 $ hg init share-parent
33 33 $ hg -q share share-parent share-child
34 34
35 $ hg -R share-child debugupgraderepo
36 abort: cannot upgrade repository; unsupported source requirement: shared
35 $ hg -R share-child debugupgraderepo --config format.sparse-revlog=no
36 abort: cannot use these actions on a share repository: sparserevlog
37 (upgrade the main repository directly)
37 38 [255]
38 39
40
39 41 Do not yet support upgrading treemanifest repos
40 42
41 43 $ hg --config experimental.treemanifest=true init treemanifest
42 44 $ hg -R treemanifest debugupgraderepo
43 45 abort: cannot upgrade repository; unsupported source requirement: treemanifest
44 46 [255]
45 47
46 48 Cannot add treemanifest requirement during upgrade
47 49
48 50 $ hg init disallowaddedreq
49 51 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
50 52 abort: cannot upgrade repository; do not support adding requirement: treemanifest
51 53 [255]
52 54
53 55 An upgrade of a repository created with recommended settings only suggests optimizations
54 56
55 57 $ hg init empty
56 58 $ cd empty
57 59 $ hg debugformat
58 60 format-variant repo
59 61 fncache: yes
60 62 dirstate-v2: no
61 63 dotencode: yes
62 64 generaldelta: yes
63 65 share-safe: yes
64 66 sparserevlog: yes
65 67 persistent-nodemap: no (no-rust !)
66 68 persistent-nodemap: yes (rust !)
67 69 copies-sdc: no
68 70 revlog-v2: no
69 71 changelog-v2: no
70 72 plain-cl-delta: yes
71 73 compression: zlib
72 74 compression-level: default
73 75 $ hg debugformat --verbose
74 76 format-variant repo config default
75 77 fncache: yes yes yes
76 78 dirstate-v2: no no no
77 79 dotencode: yes yes yes
78 80 generaldelta: yes yes yes
79 81 share-safe: yes yes yes
80 82 sparserevlog: yes yes yes
81 83 persistent-nodemap: no no no (no-rust !)
82 84 persistent-nodemap: yes yes no (rust !)
83 85 copies-sdc: no no no
84 86 revlog-v2: no no no
85 87 changelog-v2: no no no
86 88 plain-cl-delta: yes yes yes
87 89 compression: zlib zlib zlib (no-zstd !)
88 90 compression: zlib zlib zstd (zstd !)
89 91 compression-level: default default default
90 92 $ hg debugformat --verbose --config format.usefncache=no
91 93 format-variant repo config default
92 94 fncache: yes no yes
93 95 dirstate-v2: no no no
94 96 dotencode: yes no yes
95 97 generaldelta: yes yes yes
96 98 share-safe: yes yes yes
97 99 sparserevlog: yes yes yes
98 100 persistent-nodemap: no no no (no-rust !)
99 101 persistent-nodemap: yes yes no (rust !)
100 102 copies-sdc: no no no
101 103 revlog-v2: no no no
102 104 changelog-v2: no no no
103 105 plain-cl-delta: yes yes yes
104 106 compression: zlib zlib zlib (no-zstd !)
105 107 compression: zlib zlib zstd (zstd !)
106 108 compression-level: default default default
107 109 $ hg debugformat --verbose --config format.usefncache=no --color=debug
108 110 format-variant repo config default
109 111 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
110 112 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
111 113 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
112 114 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
113 115 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
114 116 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
115 117 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
116 118 [formatvariant.name.mismatchdefault|persistent-nodemap:][formatvariant.repo.mismatchdefault| yes][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
117 119 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
118 120 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
119 121 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
120 122 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
121 123 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
122 124 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
123 125 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
124 126 $ hg debugformat -Tjson
125 127 [
126 128 {
127 129 "config": true,
128 130 "default": true,
129 131 "name": "fncache",
130 132 "repo": true
131 133 },
132 134 {
133 135 "config": false,
134 136 "default": false,
135 137 "name": "dirstate-v2",
136 138 "repo": false
137 139 },
138 140 {
139 141 "config": true,
140 142 "default": true,
141 143 "name": "dotencode",
142 144 "repo": true
143 145 },
144 146 {
145 147 "config": true,
146 148 "default": true,
147 149 "name": "generaldelta",
148 150 "repo": true
149 151 },
150 152 {
151 153 "config": true,
152 154 "default": true,
153 155 "name": "share-safe",
154 156 "repo": true
155 157 },
156 158 {
157 159 "config": true,
158 160 "default": true,
159 161 "name": "sparserevlog",
160 162 "repo": true
161 163 },
162 164 {
163 165 "config": false, (no-rust !)
164 166 "config": true, (rust !)
165 167 "default": false,
166 168 "name": "persistent-nodemap",
167 169 "repo": false (no-rust !)
168 170 "repo": true (rust !)
169 171 },
170 172 {
171 173 "config": false,
172 174 "default": false,
173 175 "name": "copies-sdc",
174 176 "repo": false
175 177 },
176 178 {
177 179 "config": false,
178 180 "default": false,
179 181 "name": "revlog-v2",
180 182 "repo": false
181 183 },
182 184 {
183 185 "config": false,
184 186 "default": false,
185 187 "name": "changelog-v2",
186 188 "repo": false
187 189 },
188 190 {
189 191 "config": true,
190 192 "default": true,
191 193 "name": "plain-cl-delta",
192 194 "repo": true
193 195 },
194 196 {
195 197 "config": "zlib",
196 198 "default": "zlib", (no-zstd !)
197 199 "default": "zstd", (zstd !)
198 200 "name": "compression",
199 201 "repo": "zlib"
200 202 },
201 203 {
202 204 "config": "default",
203 205 "default": "default",
204 206 "name": "compression-level",
205 207 "repo": "default"
206 208 }
207 209 ]
208 210 $ hg debugupgraderepo
209 211 (no format upgrades found in existing repository)
210 212 performing an upgrade with "--run" will make the following changes:
211 213
212 214 requirements
213 215 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
214 216 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
215 217
216 218 no revlogs to process
217 219
218 220 additional optimizations are available by specifying "--optimize <name>":
219 221
220 222 re-delta-parent
221 223 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
222 224
223 225 re-delta-multibase
224 226 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
225 227
226 228 re-delta-all
227 229 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
228 230
229 231 re-delta-fulladd
230 232 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.
231 233
232 234
233 235 $ hg debugupgraderepo --quiet
234 236 requirements
235 237 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
236 238 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
237 239
238 240 no revlogs to process
239 241
240 242
241 243 --optimize can be used to add optimizations
242 244
243 245 $ hg debugupgrade --optimize 're-delta-parent'
244 246 (no format upgrades found in existing repository)
245 247 performing an upgrade with "--run" will make the following changes:
246 248
247 249 requirements
248 250 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
249 251 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
250 252
251 253 optimisations: re-delta-parent
252 254
253 255 re-delta-parent
254 256 deltas within internal storage will choose a new base revision if needed
255 257
256 258 processed revlogs:
257 259 - all-filelogs
258 260 - changelog
259 261 - manifest
260 262
261 263 additional optimizations are available by specifying "--optimize <name>":
262 264
263 265 re-delta-multibase
264 266 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 267
266 268 re-delta-all
267 269 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 270
269 271 re-delta-fulladd
270 272 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 273
272 274
273 275 modern form of the option
274 276
275 277 $ hg debugupgrade --optimize re-delta-parent
276 278 (no format upgrades found in existing repository)
277 279 performing an upgrade with "--run" will make the following changes:
278 280
279 281 requirements
280 282 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
281 283 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
282 284
283 285 optimisations: re-delta-parent
284 286
285 287 re-delta-parent
286 288 deltas within internal storage will choose a new base revision if needed
287 289
288 290 processed revlogs:
289 291 - all-filelogs
290 292 - changelog
291 293 - manifest
292 294
293 295 additional optimizations are available by specifying "--optimize <name>":
294 296
295 297 re-delta-multibase
296 298 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
297 299
298 300 re-delta-all
299 301 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
300 302
301 303 re-delta-fulladd
302 304 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.
303 305
304 306 $ hg debugupgrade --optimize re-delta-parent --quiet
305 307 requirements
306 308 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
307 309 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
308 310
309 311 optimisations: re-delta-parent
310 312
311 313 processed revlogs:
312 314 - all-filelogs
313 315 - changelog
314 316 - manifest
315 317
316 318
317 319 unknown optimization:
318 320
319 321 $ hg debugupgrade --optimize foobar
320 322 abort: unknown optimization action requested: foobar
321 323 (run without arguments to see valid optimizations)
322 324 [255]
323 325
324 326 Various sub-optimal detections work
325 327
326 328 $ cat > .hg/requires << EOF
327 329 > revlogv1
328 330 > store
329 331 > EOF
330 332
331 333 $ hg debugformat
332 334 format-variant repo
333 335 fncache: no
334 336 dirstate-v2: no
335 337 dotencode: no
336 338 generaldelta: no
337 339 share-safe: no
338 340 sparserevlog: no
339 341 persistent-nodemap: no
340 342 copies-sdc: no
341 343 revlog-v2: no
342 344 changelog-v2: no
343 345 plain-cl-delta: yes
344 346 compression: zlib
345 347 compression-level: default
346 348 $ hg debugformat --verbose
347 349 format-variant repo config default
348 350 fncache: no yes yes
349 351 dirstate-v2: no no no
350 352 dotencode: no yes yes
351 353 generaldelta: no yes yes
352 354 share-safe: no yes yes
353 355 sparserevlog: no yes yes
354 356 persistent-nodemap: no no no (no-rust !)
355 357 persistent-nodemap: no yes no (rust !)
356 358 copies-sdc: no no no
357 359 revlog-v2: no no no
358 360 changelog-v2: no no no
359 361 plain-cl-delta: yes yes yes
360 362 compression: zlib zlib zlib (no-zstd !)
361 363 compression: zlib zlib zstd (zstd !)
362 364 compression-level: default default default
363 365 $ hg debugformat --verbose --config format.usegeneraldelta=no
364 366 format-variant repo config default
365 367 fncache: no yes yes
366 368 dirstate-v2: no no no
367 369 dotencode: no yes yes
368 370 generaldelta: no no yes
369 371 share-safe: no yes yes
370 372 sparserevlog: no no yes
371 373 persistent-nodemap: no no no (no-rust !)
372 374 persistent-nodemap: no yes no (rust !)
373 375 copies-sdc: no no no
374 376 revlog-v2: no no no
375 377 changelog-v2: no no no
376 378 plain-cl-delta: yes yes yes
377 379 compression: zlib zlib zlib (no-zstd !)
378 380 compression: zlib zlib zstd (zstd !)
379 381 compression-level: default default default
380 382 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
381 383 format-variant repo config default
382 384 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
383 385 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
384 386 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
385 387 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
386 388 [formatvariant.name.mismatchconfig|share-safe: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
387 389 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
388 390 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
389 391 [formatvariant.name.mismatchconfig|persistent-nodemap:][formatvariant.repo.mismatchconfig| no][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
390 392 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
391 393 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
392 394 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
393 395 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
394 396 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
395 397 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
396 398 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
397 399 $ hg debugupgraderepo
398 400 note: selecting all-filelogs for processing to change: dotencode
399 401 note: selecting all-manifestlogs for processing to change: dotencode
400 402 note: selecting changelog for processing to change: dotencode
401 403
402 404 repository lacks features recommended by current config options:
403 405
404 406 fncache
405 407 long and reserved filenames may not work correctly; repository performance is sub-optimal
406 408
407 409 dotencode
408 410 storage of filenames beginning with a period or space may not work correctly
409 411
410 412 generaldelta
411 413 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
412 414
413 415 share-safe
414 416 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
415 417
416 418 sparserevlog
417 419 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.
418 420
419 421 persistent-nodemap (rust !)
420 422 persist the node -> rev mapping on disk to speedup lookup (rust !)
421 423 (rust !)
422 424
423 425 performing an upgrade with "--run" will make the following changes:
424 426
425 427 requirements
426 428 preserved: revlogv1, store
427 429 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
428 430 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
429 431
430 432 fncache
431 433 repository will be more resilient to storing certain paths and performance of certain operations should be improved
432 434
433 435 dotencode
434 436 repository will be better able to store files beginning with a space or period
435 437
436 438 generaldelta
437 439 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
438 440
439 441 share-safe
440 442 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
441 443
442 444 sparserevlog
443 445 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.
444 446
445 447 persistent-nodemap (rust !)
446 448 Speedup revision lookup by node id. (rust !)
447 449 (rust !)
448 450 processed revlogs:
449 451 - all-filelogs
450 452 - changelog
451 453 - manifest
452 454
453 455 additional optimizations are available by specifying "--optimize <name>":
454 456
455 457 re-delta-parent
456 458 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 459
458 460 re-delta-multibase
459 461 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 462
461 463 re-delta-all
462 464 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 465
464 466 re-delta-fulladd
465 467 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 468
467 469 $ hg debugupgraderepo --quiet
468 470 requirements
469 471 preserved: revlogv1, store
470 472 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
471 473 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
472 474
473 475 processed revlogs:
474 476 - all-filelogs
475 477 - changelog
476 478 - manifest
477 479
478 480
479 481 $ hg --config format.dotencode=false debugupgraderepo
480 482 note: selecting all-filelogs for processing to change: fncache
481 483 note: selecting all-manifestlogs for processing to change: fncache
482 484 note: selecting changelog for processing to change: fncache
483 485
484 486 repository lacks features recommended by current config options:
485 487
486 488 fncache
487 489 long and reserved filenames may not work correctly; repository performance is sub-optimal
488 490
489 491 generaldelta
490 492 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
491 493
492 494 share-safe
493 495 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
494 496
495 497 sparserevlog
496 498 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.
497 499
498 500 persistent-nodemap (rust !)
499 501 persist the node -> rev mapping on disk to speedup lookup (rust !)
500 502 (rust !)
501 503 repository lacks features used by the default config options:
502 504
503 505 dotencode
504 506 storage of filenames beginning with a period or space may not work correctly
505 507
506 508
507 509 performing an upgrade with "--run" will make the following changes:
508 510
509 511 requirements
510 512 preserved: revlogv1, store
511 513 added: fncache, generaldelta, share-safe, sparserevlog (no-rust !)
512 514 added: fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
513 515
514 516 fncache
515 517 repository will be more resilient to storing certain paths and performance of certain operations should be improved
516 518
517 519 generaldelta
518 520 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
519 521
520 522 share-safe
521 523 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
522 524
523 525 sparserevlog
524 526 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.
525 527
526 528 persistent-nodemap (rust !)
527 529 Speedup revision lookup by node id. (rust !)
528 530 (rust !)
529 531 processed revlogs:
530 532 - all-filelogs
531 533 - changelog
532 534 - manifest
533 535
534 536 additional optimizations are available by specifying "--optimize <name>":
535 537
536 538 re-delta-parent
537 539 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
538 540
539 541 re-delta-multibase
540 542 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
541 543
542 544 re-delta-all
543 545 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
544 546
545 547 re-delta-fulladd
546 548 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.
547 549
548 550
549 551 $ cd ..
550 552
551 553 Upgrading a repository that is already modern essentially no-ops
552 554
553 555 $ hg init modern
554 556 $ hg -R modern debugupgraderepo --run
555 557 nothing to do
556 558
557 559 Upgrading a repository to generaldelta works
558 560
559 561 $ hg --config format.usegeneraldelta=false init upgradegd
560 562 $ cd upgradegd
561 563 $ touch f0
562 564 $ hg -q commit -A -m initial
563 565 $ mkdir FooBarDirectory.d
564 566 $ touch FooBarDirectory.d/f1
565 567 $ hg -q commit -A -m 'add f1'
566 568 $ hg -q up -r 0
567 569 >>> from __future__ import absolute_import, print_function
568 570 >>> import random
569 571 >>> random.seed(0) # have a reproducible content
570 572 >>> with open("f2", "wb") as f:
571 573 ... for i in range(100000):
572 574 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
573 575 $ hg -q commit -A -m 'add f2'
574 576
575 577 make sure we have a .d file
576 578
577 579 $ ls -d .hg/store/data/*
578 580 .hg/store/data/_foo_bar_directory.d.hg
579 581 .hg/store/data/f0.i
580 582 .hg/store/data/f2.d
581 583 .hg/store/data/f2.i
582 584
583 585 $ hg debugupgraderepo --run --config format.sparse-revlog=false
584 586 note: selecting all-filelogs for processing to change: generaldelta
585 587 note: selecting all-manifestlogs for processing to change: generaldelta
586 588 note: selecting changelog for processing to change: generaldelta
587 589
588 590 upgrade will perform the following actions:
589 591
590 592 requirements
591 593 preserved: dotencode, fncache, revlogv1, share-safe, store (no-rust !)
592 594 preserved: dotencode, fncache, persistent-nodemap, revlogv1, share-safe, store (rust !)
593 595 added: generaldelta
594 596
595 597 generaldelta
596 598 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
597 599
598 600 processed revlogs:
599 601 - all-filelogs
600 602 - changelog
601 603 - manifest
602 604
603 605 beginning upgrade...
604 606 repository locked and read-only
605 607 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
606 608 (it is safe to interrupt this process any time before data migration completes)
607 609 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
608 610 migrating 519 KB in store; 1.05 MB tracked data
609 611 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
610 612 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
611 613 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
612 614 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
613 615 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
614 616 finished migrating 3 changelog revisions; change in size: 0 bytes
615 617 finished migrating 9 total revisions; total change in store size: -17 bytes
616 618 copying phaseroots
617 619 copying requires
618 620 data fully upgraded in a temporary repository
619 621 marking source repository as being upgraded; clients will be unable to read from repository
620 622 starting in-place swap of repository data
621 623 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
622 624 replacing store...
623 625 store replacement complete; repository was inconsistent for *s (glob)
624 626 finalizing requirements file and making repository readable again
625 627 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
626 628 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
627 629 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
628 630
629 631 Original requirements backed up
630 632
631 633 $ cat .hg/upgradebackup.*/requires
632 634 share-safe
633 635 $ cat .hg/upgradebackup.*/store/requires
634 636 dotencode
635 637 fncache
636 638 persistent-nodemap (rust !)
637 639 revlogv1
638 640 store
639 641 upgradeinprogress
640 642
641 643 generaldelta added to original requirements files
642 644
643 645 $ hg debugrequires
644 646 dotencode
645 647 fncache
646 648 generaldelta
647 649 persistent-nodemap (rust !)
648 650 revlogv1
649 651 share-safe
650 652 store
651 653
652 654 store directory has files we expect
653 655
654 656 $ ls .hg/store
655 657 00changelog.i
656 658 00manifest.i
657 659 data
658 660 fncache
659 661 phaseroots
660 662 requires
661 663 undo
662 664 undo.backupfiles
663 665 undo.phaseroots
664 666
665 667 manifest should be generaldelta
666 668
667 669 $ hg debugrevlog -m | grep flags
668 670 flags : inline, generaldelta
669 671
670 672 verify should be happy
671 673
672 674 $ hg verify
673 675 checking changesets
674 676 checking manifests
675 677 crosschecking files in changesets and manifests
676 678 checking files
677 679 checked 3 changesets with 3 changes to 3 files
678 680
679 681 old store should be backed up
680 682
681 683 $ ls -d .hg/upgradebackup.*/
682 684 .hg/upgradebackup.*/ (glob)
683 685 $ ls .hg/upgradebackup.*/store
684 686 00changelog.i
685 687 00manifest.i
686 688 data
687 689 fncache
688 690 phaseroots
689 691 requires
690 692 undo
691 693 undo.backup.fncache
692 694 undo.backupfiles
693 695 undo.phaseroots
694 696
695 697 unless --no-backup is passed
696 698
697 699 $ rm -rf .hg/upgradebackup.*/
698 700 $ hg debugupgraderepo --run --no-backup
699 701 note: selecting all-filelogs for processing to change: sparserevlog
700 702 note: selecting all-manifestlogs for processing to change: sparserevlog
701 703 note: selecting changelog for processing to change: sparserevlog
702 704
703 705 upgrade will perform the following actions:
704 706
705 707 requirements
706 708 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
707 709 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
708 710 added: sparserevlog
709 711
710 712 sparserevlog
711 713 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.
712 714
713 715 processed revlogs:
714 716 - all-filelogs
715 717 - changelog
716 718 - manifest
717 719
718 720 beginning upgrade...
719 721 repository locked and read-only
720 722 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
721 723 (it is safe to interrupt this process any time before data migration completes)
722 724 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
723 725 migrating 519 KB in store; 1.05 MB tracked data
724 726 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
725 727 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
726 728 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
727 729 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
728 730 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
729 731 finished migrating 3 changelog revisions; change in size: 0 bytes
730 732 finished migrating 9 total revisions; total change in store size: 0 bytes
731 733 copying phaseroots
732 734 copying requires
733 735 data fully upgraded in a temporary repository
734 736 marking source repository as being upgraded; clients will be unable to read from repository
735 737 starting in-place swap of repository data
736 738 replacing store...
737 739 store replacement complete; repository was inconsistent for * (glob)
738 740 finalizing requirements file and making repository readable again
739 741 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
740 742 $ ls -1 .hg/ | grep upgradebackup
741 743 [1]
742 744
743 745 We can restrict optimization to some revlog:
744 746
745 747 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
746 748 upgrade will perform the following actions:
747 749
748 750 requirements
749 751 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
750 752 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
751 753
752 754 optimisations: re-delta-parent
753 755
754 756 re-delta-parent
755 757 deltas within internal storage will choose a new base revision if needed
756 758
757 759 processed revlogs:
758 760 - manifest
759 761
760 762 beginning upgrade...
761 763 repository locked and read-only
762 764 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
763 765 (it is safe to interrupt this process any time before data migration completes)
764 766 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
765 767 migrating 519 KB in store; 1.05 MB tracked data
766 768 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
767 769 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
768 770 blindly copying data/f0.i containing 1 revisions
769 771 blindly copying data/f2.i containing 1 revisions
770 772 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
771 773 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
772 774 cloning 3 revisions from 00manifest.i
773 775 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
774 776 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
775 777 blindly copying 00changelog.i containing 3 revisions
776 778 finished migrating 3 changelog revisions; change in size: 0 bytes
777 779 finished migrating 9 total revisions; total change in store size: 0 bytes
778 780 copying phaseroots
779 781 copying requires
780 782 data fully upgraded in a temporary repository
781 783 marking source repository as being upgraded; clients will be unable to read from repository
782 784 starting in-place swap of repository data
783 785 replacing store...
784 786 store replacement complete; repository was inconsistent for *s (glob)
785 787 finalizing requirements file and making repository readable again
786 788 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
787 789
788 790 Check that the repo still works fine
789 791
790 792 $ hg log -G --stat
791 793 @ changeset: 2:76d4395f5413 (no-py3 !)
792 794 @ changeset: 2:fca376863211 (py3 !)
793 795 | tag: tip
794 796 | parent: 0:ba592bf28da2
795 797 | user: test
796 798 | date: Thu Jan 01 00:00:00 1970 +0000
797 799 | summary: add f2
798 800 |
799 801 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
800 802 | 1 files changed, 100000 insertions(+), 0 deletions(-)
801 803 |
802 804 | o changeset: 1:2029ce2354e2
803 805 |/ user: test
804 806 | date: Thu Jan 01 00:00:00 1970 +0000
805 807 | summary: add f1
806 808 |
807 809 |
808 810 o changeset: 0:ba592bf28da2
809 811 user: test
810 812 date: Thu Jan 01 00:00:00 1970 +0000
811 813 summary: initial
812 814
813 815
814 816
815 817 $ hg verify
816 818 checking changesets
817 819 checking manifests
818 820 crosschecking files in changesets and manifests
819 821 checking files
820 822 checked 3 changesets with 3 changes to 3 files
821 823
822 824 Check we can select negatively
823 825
824 826 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
825 827 upgrade will perform the following actions:
826 828
827 829 requirements
828 830 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
829 831 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
830 832
831 833 optimisations: re-delta-parent
832 834
833 835 re-delta-parent
834 836 deltas within internal storage will choose a new base revision if needed
835 837
836 838 processed revlogs:
837 839 - all-filelogs
838 840 - changelog
839 841
840 842 beginning upgrade...
841 843 repository locked and read-only
842 844 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
843 845 (it is safe to interrupt this process any time before data migration completes)
844 846 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
845 847 migrating 519 KB in store; 1.05 MB tracked data
846 848 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
847 849 cloning 1 revisions from data/FooBarDirectory.d/f1.i
848 850 cloning 1 revisions from data/f0.i
849 851 cloning 1 revisions from data/f2.i
850 852 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
851 853 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
852 854 blindly copying 00manifest.i containing 3 revisions
853 855 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
854 856 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
855 857 cloning 3 revisions from 00changelog.i
856 858 finished migrating 3 changelog revisions; change in size: 0 bytes
857 859 finished migrating 9 total revisions; total change in store size: 0 bytes
858 860 copying phaseroots
859 861 copying requires
860 862 data fully upgraded in a temporary repository
861 863 marking source repository as being upgraded; clients will be unable to read from repository
862 864 starting in-place swap of repository data
863 865 replacing store...
864 866 store replacement complete; repository was inconsistent for *s (glob)
865 867 finalizing requirements file and making repository readable again
866 868 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
867 869 $ hg verify
868 870 checking changesets
869 871 checking manifests
870 872 crosschecking files in changesets and manifests
871 873 checking files
872 874 checked 3 changesets with 3 changes to 3 files
873 875
874 876 Check that we can select changelog only
875 877
876 878 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
877 879 upgrade will perform the following actions:
878 880
879 881 requirements
880 882 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
881 883 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
882 884
883 885 optimisations: re-delta-parent
884 886
885 887 re-delta-parent
886 888 deltas within internal storage will choose a new base revision if needed
887 889
888 890 processed revlogs:
889 891 - changelog
890 892
891 893 beginning upgrade...
892 894 repository locked and read-only
893 895 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
894 896 (it is safe to interrupt this process any time before data migration completes)
895 897 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
896 898 migrating 519 KB in store; 1.05 MB tracked data
897 899 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
898 900 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
899 901 blindly copying data/f0.i containing 1 revisions
900 902 blindly copying data/f2.i containing 1 revisions
901 903 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
902 904 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
903 905 blindly copying 00manifest.i containing 3 revisions
904 906 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
905 907 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
906 908 cloning 3 revisions from 00changelog.i
907 909 finished migrating 3 changelog revisions; change in size: 0 bytes
908 910 finished migrating 9 total revisions; total change in store size: 0 bytes
909 911 copying phaseroots
910 912 copying requires
911 913 data fully upgraded in a temporary repository
912 914 marking source repository as being upgraded; clients will be unable to read from repository
913 915 starting in-place swap of repository data
914 916 replacing store...
915 917 store replacement complete; repository was inconsistent for *s (glob)
916 918 finalizing requirements file and making repository readable again
917 919 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
918 920 $ hg verify
919 921 checking changesets
920 922 checking manifests
921 923 crosschecking files in changesets and manifests
922 924 checking files
923 925 checked 3 changesets with 3 changes to 3 files
924 926
925 927 Check that we can select filelog only
926 928
927 929 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
928 930 upgrade will perform the following actions:
929 931
930 932 requirements
931 933 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
932 934 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
933 935
934 936 optimisations: re-delta-parent
935 937
936 938 re-delta-parent
937 939 deltas within internal storage will choose a new base revision if needed
938 940
939 941 processed revlogs:
940 942 - all-filelogs
941 943
942 944 beginning upgrade...
943 945 repository locked and read-only
944 946 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
945 947 (it is safe to interrupt this process any time before data migration completes)
946 948 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
947 949 migrating 519 KB in store; 1.05 MB tracked data
948 950 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
949 951 cloning 1 revisions from data/FooBarDirectory.d/f1.i
950 952 cloning 1 revisions from data/f0.i
951 953 cloning 1 revisions from data/f2.i
952 954 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
953 955 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
954 956 blindly copying 00manifest.i containing 3 revisions
955 957 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
956 958 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
957 959 blindly copying 00changelog.i containing 3 revisions
958 960 finished migrating 3 changelog revisions; change in size: 0 bytes
959 961 finished migrating 9 total revisions; total change in store size: 0 bytes
960 962 copying phaseroots
961 963 copying requires
962 964 data fully upgraded in a temporary repository
963 965 marking source repository as being upgraded; clients will be unable to read from repository
964 966 starting in-place swap of repository data
965 967 replacing store...
966 968 store replacement complete; repository was inconsistent for *s (glob)
967 969 finalizing requirements file and making repository readable again
968 970 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
969 971 $ hg verify
970 972 checking changesets
971 973 checking manifests
972 974 crosschecking files in changesets and manifests
973 975 checking files
974 976 checked 3 changesets with 3 changes to 3 files
975 977
976 978
977 979 Check you can't skip revlog clone during important format downgrade
978 980
979 981 $ echo "[format]" > .hg/hgrc
980 982 $ echo "sparse-revlog=no" >> .hg/hgrc
981 983 $ hg debugupgrade --optimize re-delta-parent --no-manifest --no-backup --quiet
982 984 warning: ignoring --no-manifest, as upgrade is changing: sparserevlog
983 985
984 986 requirements
985 987 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
986 988 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
987 989 removed: sparserevlog
988 990
989 991 optimisations: re-delta-parent
990 992
991 993 processed revlogs:
992 994 - all-filelogs
993 995 - changelog
994 996 - manifest
995 997
996 998 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
997 999 note: selecting all-filelogs for processing to change: sparserevlog
998 1000 note: selecting changelog for processing to change: sparserevlog
999 1001
1000 1002 upgrade will perform the following actions:
1001 1003
1002 1004 requirements
1003 1005 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1004 1006 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1005 1007 removed: sparserevlog
1006 1008
1007 1009 optimisations: re-delta-parent
1008 1010
1009 1011 re-delta-parent
1010 1012 deltas within internal storage will choose a new base revision if needed
1011 1013
1012 1014 processed revlogs:
1013 1015 - all-filelogs
1014 1016 - changelog
1015 1017 - manifest
1016 1018
1017 1019 beginning upgrade...
1018 1020 repository locked and read-only
1019 1021 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1020 1022 (it is safe to interrupt this process any time before data migration completes)
1021 1023 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1022 1024 migrating 519 KB in store; 1.05 MB tracked data
1023 1025 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1024 1026 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1025 1027 cloning 1 revisions from data/f0.i
1026 1028 cloning 1 revisions from data/f2.i
1027 1029 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1028 1030 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1029 1031 cloning 3 revisions from 00manifest.i
1030 1032 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1031 1033 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1032 1034 cloning 3 revisions from 00changelog.i
1033 1035 finished migrating 3 changelog revisions; change in size: 0 bytes
1034 1036 finished migrating 9 total revisions; total change in store size: 0 bytes
1035 1037 copying phaseroots
1036 1038 copying requires
1037 1039 data fully upgraded in a temporary repository
1038 1040 marking source repository as being upgraded; clients will be unable to read from repository
1039 1041 starting in-place swap of repository data
1040 1042 replacing store...
1041 1043 store replacement complete; repository was inconsistent for *s (glob)
1042 1044 finalizing requirements file and making repository readable again
1043 1045 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1044 1046 $ hg verify
1045 1047 checking changesets
1046 1048 checking manifests
1047 1049 crosschecking files in changesets and manifests
1048 1050 checking files
1049 1051 checked 3 changesets with 3 changes to 3 files
1050 1052
1051 1053 Check you can't skip revlog clone during important format upgrade
1052 1054
1053 1055 $ echo "sparse-revlog=yes" >> .hg/hgrc
1054 1056 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
1055 1057 note: selecting all-filelogs for processing to change: sparserevlog
1056 1058 note: selecting changelog for processing to change: sparserevlog
1057 1059
1058 1060 upgrade will perform the following actions:
1059 1061
1060 1062 requirements
1061 1063 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1062 1064 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1063 1065 added: sparserevlog
1064 1066
1065 1067 optimisations: re-delta-parent
1066 1068
1067 1069 sparserevlog
1068 1070 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.
1069 1071
1070 1072 re-delta-parent
1071 1073 deltas within internal storage will choose a new base revision if needed
1072 1074
1073 1075 processed revlogs:
1074 1076 - all-filelogs
1075 1077 - changelog
1076 1078 - manifest
1077 1079
1078 1080 beginning upgrade...
1079 1081 repository locked and read-only
1080 1082 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1081 1083 (it is safe to interrupt this process any time before data migration completes)
1082 1084 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1083 1085 migrating 519 KB in store; 1.05 MB tracked data
1084 1086 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1085 1087 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1086 1088 cloning 1 revisions from data/f0.i
1087 1089 cloning 1 revisions from data/f2.i
1088 1090 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1089 1091 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1090 1092 cloning 3 revisions from 00manifest.i
1091 1093 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1092 1094 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1093 1095 cloning 3 revisions from 00changelog.i
1094 1096 finished migrating 3 changelog revisions; change in size: 0 bytes
1095 1097 finished migrating 9 total revisions; total change in store size: 0 bytes
1096 1098 copying phaseroots
1097 1099 copying requires
1098 1100 data fully upgraded in a temporary repository
1099 1101 marking source repository as being upgraded; clients will be unable to read from repository
1100 1102 starting in-place swap of repository data
1101 1103 replacing store...
1102 1104 store replacement complete; repository was inconsistent for *s (glob)
1103 1105 finalizing requirements file and making repository readable again
1104 1106 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1105 1107 $ hg verify
1106 1108 checking changesets
1107 1109 checking manifests
1108 1110 crosschecking files in changesets and manifests
1109 1111 checking files
1110 1112 checked 3 changesets with 3 changes to 3 files
1111 1113
1112 1114 $ cd ..
1113 1115
1114 1116 store files with special filenames aren't encoded during copy
1115 1117
1116 1118 $ hg init store-filenames
1117 1119 $ cd store-filenames
1118 1120 $ touch foo
1119 1121 $ hg -q commit -A -m initial
1120 1122 $ touch .hg/store/.XX_special_filename
1121 1123
1122 1124 $ hg debugupgraderepo --run
1123 1125 nothing to do
1124 1126 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
1125 1127 upgrade will perform the following actions:
1126 1128
1127 1129 requirements
1128 1130 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1129 1131 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1130 1132
1131 1133 optimisations: re-delta-fulladd
1132 1134
1133 1135 re-delta-fulladd
1134 1136 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
1135 1137
1136 1138 processed revlogs:
1137 1139 - all-filelogs
1138 1140 - changelog
1139 1141 - manifest
1140 1142
1141 1143 beginning upgrade...
1142 1144 repository locked and read-only
1143 1145 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1144 1146 (it is safe to interrupt this process any time before data migration completes)
1145 1147 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1146 1148 migrating 301 bytes in store; 107 bytes tracked data
1147 1149 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1148 1150 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1149 1151 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1150 1152 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1151 1153 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1152 1154 finished migrating 1 changelog revisions; change in size: 0 bytes
1153 1155 finished migrating 3 total revisions; total change in store size: 0 bytes
1154 1156 copying .XX_special_filename
1155 1157 copying phaseroots
1156 1158 copying requires
1157 1159 data fully upgraded in a temporary repository
1158 1160 marking source repository as being upgraded; clients will be unable to read from repository
1159 1161 starting in-place swap of repository data
1160 1162 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1161 1163 replacing store...
1162 1164 store replacement complete; repository was inconsistent for *s (glob)
1163 1165 finalizing requirements file and making repository readable again
1164 1166 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1165 1167 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1166 1168 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1167 1169
1168 1170 fncache is valid after upgrade
1169 1171
1170 1172 $ hg debugrebuildfncache
1171 1173 fncache already up to date
1172 1174
1173 1175 $ cd ..
1174 1176
1175 1177 Check upgrading a large file repository
1176 1178 ---------------------------------------
1177 1179
1178 1180 $ hg init largefilesrepo
1179 1181 $ cat << EOF >> largefilesrepo/.hg/hgrc
1180 1182 > [extensions]
1181 1183 > largefiles =
1182 1184 > EOF
1183 1185
1184 1186 $ cd largefilesrepo
1185 1187 $ touch foo
1186 1188 $ hg add --large foo
1187 1189 $ hg -q commit -m initial
1188 1190 $ hg debugrequires
1189 1191 dotencode
1190 1192 fncache
1191 1193 generaldelta
1192 1194 largefiles
1193 1195 persistent-nodemap (rust !)
1194 1196 revlogv1
1195 1197 share-safe
1196 1198 sparserevlog
1197 1199 store
1198 1200
1199 1201 $ hg debugupgraderepo --run
1200 1202 nothing to do
1201 1203 $ hg debugrequires
1202 1204 dotencode
1203 1205 fncache
1204 1206 generaldelta
1205 1207 largefiles
1206 1208 persistent-nodemap (rust !)
1207 1209 revlogv1
1208 1210 share-safe
1209 1211 sparserevlog
1210 1212 store
1211 1213
1212 1214 $ cat << EOF >> .hg/hgrc
1213 1215 > [extensions]
1214 1216 > lfs =
1215 1217 > [lfs]
1216 1218 > threshold = 10
1217 1219 > EOF
1218 1220 $ echo '123456789012345' > lfs.bin
1219 1221 $ hg ci -Am 'lfs.bin'
1220 1222 adding lfs.bin
1221 1223 $ hg debugrequires | grep lfs
1222 1224 lfs
1223 1225 $ find .hg/store/lfs -type f
1224 1226 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1225 1227
1226 1228 $ hg debugupgraderepo --run
1227 1229 nothing to do
1228 1230
1229 1231 $ hg debugrequires | grep lfs
1230 1232 lfs
1231 1233 $ find .hg/store/lfs -type f
1232 1234 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1233 1235 $ hg verify
1234 1236 checking changesets
1235 1237 checking manifests
1236 1238 crosschecking files in changesets and manifests
1237 1239 checking files
1238 1240 checked 2 changesets with 2 changes to 2 files
1239 1241 $ hg debugdata lfs.bin 0
1240 1242 version https://git-lfs.github.com/spec/v1
1241 1243 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1242 1244 size 16
1243 1245 x-is-binary 0
1244 1246
1245 1247 $ cd ..
1246 1248
1247 1249 repository config is taken in account
1248 1250 -------------------------------------
1249 1251
1250 1252 $ cat << EOF >> $HGRCPATH
1251 1253 > [format]
1252 1254 > maxchainlen = 1
1253 1255 > EOF
1254 1256
1255 1257 $ hg init localconfig
1256 1258 $ cd localconfig
1257 1259 $ cat << EOF > file
1258 1260 > some content
1259 1261 > with some length
1260 1262 > to make sure we get a delta
1261 1263 > after changes
1262 1264 > very long
1263 1265 > very long
1264 1266 > very long
1265 1267 > very long
1266 1268 > very long
1267 1269 > very long
1268 1270 > very long
1269 1271 > very long
1270 1272 > very long
1271 1273 > very long
1272 1274 > very long
1273 1275 > EOF
1274 1276 $ hg -q commit -A -m A
1275 1277 $ echo "new line" >> file
1276 1278 $ hg -q commit -m B
1277 1279 $ echo "new line" >> file
1278 1280 $ hg -q commit -m C
1279 1281
1280 1282 $ cat << EOF >> .hg/hgrc
1281 1283 > [format]
1282 1284 > maxchainlen = 9001
1283 1285 > EOF
1284 1286 $ hg config format
1285 1287 format.revlog-compression=$BUNDLE2_COMPRESSIONS$
1286 1288 format.maxchainlen=9001
1287 1289 $ hg debugdeltachain file
1288 1290 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1289 1291 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1290 1292 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1291 1293 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1292 1294
1293 1295 $ hg debugupgraderepo --run --optimize 're-delta-all'
1294 1296 upgrade will perform the following actions:
1295 1297
1296 1298 requirements
1297 1299 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1298 1300 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1299 1301
1300 1302 optimisations: re-delta-all
1301 1303
1302 1304 re-delta-all
1303 1305 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1304 1306
1305 1307 processed revlogs:
1306 1308 - all-filelogs
1307 1309 - changelog
1308 1310 - manifest
1309 1311
1310 1312 beginning upgrade...
1311 1313 repository locked and read-only
1312 1314 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1313 1315 (it is safe to interrupt this process any time before data migration completes)
1314 1316 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1315 1317 migrating 1019 bytes in store; 882 bytes tracked data
1316 1318 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1317 1319 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1318 1320 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1319 1321 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1320 1322 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1321 1323 finished migrating 3 changelog revisions; change in size: 0 bytes
1322 1324 finished migrating 9 total revisions; total change in store size: -9 bytes
1323 1325 copying phaseroots
1324 1326 copying requires
1325 1327 data fully upgraded in a temporary repository
1326 1328 marking source repository as being upgraded; clients will be unable to read from repository
1327 1329 starting in-place swap of repository data
1328 1330 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1329 1331 replacing store...
1330 1332 store replacement complete; repository was inconsistent for *s (glob)
1331 1333 finalizing requirements file and making repository readable again
1332 1334 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1333 1335 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1334 1336 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1335 1337 $ hg debugdeltachain file
1336 1338 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1337 1339 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1338 1340 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1339 1341 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1340 1342 $ cd ..
1341 1343
1342 1344 $ cat << EOF >> $HGRCPATH
1343 1345 > [format]
1344 1346 > maxchainlen = 9001
1345 1347 > EOF
1346 1348
1347 1349 Check upgrading a sparse-revlog repository
1348 1350 ---------------------------------------
1349 1351
1350 1352 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1351 1353 $ cd sparserevlogrepo
1352 1354 $ touch foo
1353 1355 $ hg add foo
1354 1356 $ hg -q commit -m "foo"
1355 1357 $ hg debugrequires
1356 1358 dotencode
1357 1359 fncache
1358 1360 generaldelta
1359 1361 persistent-nodemap (rust !)
1360 1362 revlogv1
1361 1363 share-safe
1362 1364 store
1363 1365
1364 1366 Check that we can add the sparse-revlog format requirement
1365 1367 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1366 1368 upgrade will perform the following actions:
1367 1369
1368 1370 requirements
1369 1371 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1370 1372 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1371 1373 added: sparserevlog
1372 1374
1373 1375 processed revlogs:
1374 1376 - all-filelogs
1375 1377 - changelog
1376 1378 - manifest
1377 1379
1378 1380 $ hg debugrequires
1379 1381 dotencode
1380 1382 fncache
1381 1383 generaldelta
1382 1384 persistent-nodemap (rust !)
1383 1385 revlogv1
1384 1386 share-safe
1385 1387 sparserevlog
1386 1388 store
1387 1389
1388 1390 Check that we can remove the sparse-revlog format requirement
1389 1391 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1390 1392 upgrade will perform the following actions:
1391 1393
1392 1394 requirements
1393 1395 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1394 1396 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1395 1397 removed: sparserevlog
1396 1398
1397 1399 processed revlogs:
1398 1400 - all-filelogs
1399 1401 - changelog
1400 1402 - manifest
1401 1403
1402 1404 $ hg debugrequires
1403 1405 dotencode
1404 1406 fncache
1405 1407 generaldelta
1406 1408 persistent-nodemap (rust !)
1407 1409 revlogv1
1408 1410 share-safe
1409 1411 store
1410 1412
1411 1413 #if zstd
1412 1414
1413 1415 Check upgrading to a zstd revlog
1414 1416 --------------------------------
1415 1417
1416 1418 upgrade
1417 1419
1418 1420 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1419 1421 upgrade will perform the following actions:
1420 1422
1421 1423 requirements
1422 1424 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1423 1425 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1424 1426 added: revlog-compression-zstd, sparserevlog
1425 1427
1426 1428 processed revlogs:
1427 1429 - all-filelogs
1428 1430 - changelog
1429 1431 - manifest
1430 1432
1431 1433 $ hg debugformat -v
1432 1434 format-variant repo config default
1433 1435 fncache: yes yes yes
1434 1436 dirstate-v2: no no no
1435 1437 dotencode: yes yes yes
1436 1438 generaldelta: yes yes yes
1437 1439 share-safe: yes yes yes
1438 1440 sparserevlog: yes yes yes
1439 1441 persistent-nodemap: no no no (no-rust !)
1440 1442 persistent-nodemap: yes yes no (rust !)
1441 1443 copies-sdc: no no no
1442 1444 revlog-v2: no no no
1443 1445 changelog-v2: no no no
1444 1446 plain-cl-delta: yes yes yes
1445 1447 compression: zlib zlib zlib (no-zstd !)
1446 1448 compression: zstd zlib zstd (zstd !)
1447 1449 compression-level: default default default
1448 1450 $ hg debugrequires
1449 1451 dotencode
1450 1452 fncache
1451 1453 generaldelta
1452 1454 persistent-nodemap (rust !)
1453 1455 revlog-compression-zstd
1454 1456 revlogv1
1455 1457 share-safe
1456 1458 sparserevlog
1457 1459 store
1458 1460
1459 1461 downgrade
1460 1462
1461 1463 $ hg debugupgraderepo --run --no-backup --quiet
1462 1464 upgrade will perform the following actions:
1463 1465
1464 1466 requirements
1465 1467 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1466 1468 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1467 1469 removed: revlog-compression-zstd
1468 1470
1469 1471 processed revlogs:
1470 1472 - all-filelogs
1471 1473 - changelog
1472 1474 - manifest
1473 1475
1474 1476 $ hg debugformat -v
1475 1477 format-variant repo config default
1476 1478 fncache: yes yes yes
1477 1479 dirstate-v2: no no no
1478 1480 dotencode: yes yes yes
1479 1481 generaldelta: yes yes yes
1480 1482 share-safe: yes yes yes
1481 1483 sparserevlog: yes yes yes
1482 1484 persistent-nodemap: no no no (no-rust !)
1483 1485 persistent-nodemap: yes yes no (rust !)
1484 1486 copies-sdc: no no no
1485 1487 revlog-v2: no no no
1486 1488 changelog-v2: no no no
1487 1489 plain-cl-delta: yes yes yes
1488 1490 compression: zlib zlib zlib (no-zstd !)
1489 1491 compression: zlib zlib zstd (zstd !)
1490 1492 compression-level: default default default
1491 1493 $ hg debugrequires
1492 1494 dotencode
1493 1495 fncache
1494 1496 generaldelta
1495 1497 persistent-nodemap (rust !)
1496 1498 revlogv1
1497 1499 share-safe
1498 1500 sparserevlog
1499 1501 store
1500 1502
1501 1503 upgrade from hgrc
1502 1504
1503 1505 $ cat >> .hg/hgrc << EOF
1504 1506 > [format]
1505 1507 > revlog-compression=zstd
1506 1508 > EOF
1507 1509 $ hg debugupgraderepo --run --no-backup --quiet
1508 1510 upgrade will perform the following actions:
1509 1511
1510 1512 requirements
1511 1513 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1512 1514 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1513 1515 added: revlog-compression-zstd
1514 1516
1515 1517 processed revlogs:
1516 1518 - all-filelogs
1517 1519 - changelog
1518 1520 - manifest
1519 1521
1520 1522 $ hg debugformat -v
1521 1523 format-variant repo config default
1522 1524 fncache: yes yes yes
1523 1525 dirstate-v2: no no no
1524 1526 dotencode: yes yes yes
1525 1527 generaldelta: yes yes yes
1526 1528 share-safe: yes yes yes
1527 1529 sparserevlog: yes yes yes
1528 1530 persistent-nodemap: no no no (no-rust !)
1529 1531 persistent-nodemap: yes yes no (rust !)
1530 1532 copies-sdc: no no no
1531 1533 revlog-v2: no no no
1532 1534 changelog-v2: no no no
1533 1535 plain-cl-delta: yes yes yes
1534 1536 compression: zlib zlib zlib (no-zstd !)
1535 1537 compression: zstd zstd zstd (zstd !)
1536 1538 compression-level: default default default
1537 1539 $ hg debugrequires
1538 1540 dotencode
1539 1541 fncache
1540 1542 generaldelta
1541 1543 persistent-nodemap (rust !)
1542 1544 revlog-compression-zstd
1543 1545 revlogv1
1544 1546 share-safe
1545 1547 sparserevlog
1546 1548 store
1547 1549
1548 1550 #endif
1549 1551
1550 1552 Check upgrading to a revlog format supporting sidedata
1551 1553 ------------------------------------------------------
1552 1554
1553 1555 upgrade
1554 1556
1555 1557 $ hg debugsidedata -c 0
1556 1558 $ hg --config experimental.revlogv2=enable-unstable-format-and-corrupt-my-data debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1557 1559 upgrade will perform the following actions:
1558 1560
1559 1561 requirements
1560 1562 preserved: dotencode, fncache, generaldelta, share-safe, store (no-zstd !)
1561 1563 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1562 1564 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1563 1565 removed: revlogv1
1564 1566 added: exp-revlogv2.2 (zstd !)
1565 1567 added: exp-revlogv2.2, sparserevlog (no-zstd !)
1566 1568
1567 1569 processed revlogs:
1568 1570 - all-filelogs
1569 1571 - changelog
1570 1572 - manifest
1571 1573
1572 1574 $ hg debugformat -v
1573 1575 format-variant repo config default
1574 1576 fncache: yes yes yes
1575 1577 dirstate-v2: no no no
1576 1578 dotencode: yes yes yes
1577 1579 generaldelta: yes yes yes
1578 1580 share-safe: yes yes yes
1579 1581 sparserevlog: yes yes yes
1580 1582 persistent-nodemap: no no no (no-rust !)
1581 1583 persistent-nodemap: yes yes no (rust !)
1582 1584 copies-sdc: no no no
1583 1585 revlog-v2: yes no no
1584 1586 changelog-v2: no no no
1585 1587 plain-cl-delta: yes yes yes
1586 1588 compression: zlib zlib zlib (no-zstd !)
1587 1589 compression: zstd zstd zstd (zstd !)
1588 1590 compression-level: default default default
1589 1591 $ hg debugrequires
1590 1592 dotencode
1591 1593 exp-revlogv2.2
1592 1594 fncache
1593 1595 generaldelta
1594 1596 persistent-nodemap (rust !)
1595 1597 revlog-compression-zstd (zstd !)
1596 1598 share-safe
1597 1599 sparserevlog
1598 1600 store
1599 1601 $ hg debugsidedata -c 0
1600 1602 2 sidedata entries
1601 1603 entry-0001 size 4
1602 1604 entry-0002 size 32
1603 1605
1604 1606 downgrade
1605 1607
1606 1608 $ hg debugupgraderepo --config experimental.revlogv2=no --run --no-backup --quiet
1607 1609 upgrade will perform the following actions:
1608 1610
1609 1611 requirements
1610 1612 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1611 1613 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1612 1614 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1613 1615 removed: exp-revlogv2.2
1614 1616 added: revlogv1
1615 1617
1616 1618 processed revlogs:
1617 1619 - all-filelogs
1618 1620 - changelog
1619 1621 - manifest
1620 1622
1621 1623 $ hg debugformat -v
1622 1624 format-variant repo config default
1623 1625 fncache: yes yes yes
1624 1626 dirstate-v2: no no no
1625 1627 dotencode: yes yes yes
1626 1628 generaldelta: yes yes yes
1627 1629 share-safe: yes yes yes
1628 1630 sparserevlog: yes yes yes
1629 1631 persistent-nodemap: no no no (no-rust !)
1630 1632 persistent-nodemap: yes yes no (rust !)
1631 1633 copies-sdc: no no no
1632 1634 revlog-v2: no no no
1633 1635 changelog-v2: no no no
1634 1636 plain-cl-delta: yes yes yes
1635 1637 compression: zlib zlib zlib (no-zstd !)
1636 1638 compression: zstd zstd zstd (zstd !)
1637 1639 compression-level: default default default
1638 1640 $ hg debugrequires
1639 1641 dotencode
1640 1642 fncache
1641 1643 generaldelta
1642 1644 persistent-nodemap (rust !)
1643 1645 revlog-compression-zstd (zstd !)
1644 1646 revlogv1
1645 1647 share-safe
1646 1648 sparserevlog
1647 1649 store
1648 1650 $ hg debugsidedata -c 0
1649 1651
1650 1652 upgrade from hgrc
1651 1653
1652 1654 $ cat >> .hg/hgrc << EOF
1653 1655 > [experimental]
1654 1656 > revlogv2=enable-unstable-format-and-corrupt-my-data
1655 1657 > EOF
1656 1658 $ hg debugupgraderepo --run --no-backup --quiet
1657 1659 upgrade will perform the following actions:
1658 1660
1659 1661 requirements
1660 1662 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1661 1663 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1662 1664 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1663 1665 removed: revlogv1
1664 1666 added: exp-revlogv2.2
1665 1667
1666 1668 processed revlogs:
1667 1669 - all-filelogs
1668 1670 - changelog
1669 1671 - manifest
1670 1672
1671 1673 $ hg debugformat -v
1672 1674 format-variant repo config default
1673 1675 fncache: yes yes yes
1674 1676 dirstate-v2: no no no
1675 1677 dotencode: yes yes yes
1676 1678 generaldelta: yes yes yes
1677 1679 share-safe: yes yes yes
1678 1680 sparserevlog: yes yes yes
1679 1681 persistent-nodemap: no no no (no-rust !)
1680 1682 persistent-nodemap: yes yes no (rust !)
1681 1683 copies-sdc: no no no
1682 1684 revlog-v2: yes yes no
1683 1685 changelog-v2: no no no
1684 1686 plain-cl-delta: yes yes yes
1685 1687 compression: zlib zlib zlib (no-zstd !)
1686 1688 compression: zstd zstd zstd (zstd !)
1687 1689 compression-level: default default default
1688 1690 $ hg debugrequires
1689 1691 dotencode
1690 1692 exp-revlogv2.2
1691 1693 fncache
1692 1694 generaldelta
1693 1695 persistent-nodemap (rust !)
1694 1696 revlog-compression-zstd (zstd !)
1695 1697 share-safe
1696 1698 sparserevlog
1697 1699 store
1698 1700 $ hg debugsidedata -c 0
1699 1701
1700 1702 Demonstrate that nothing to perform upgrade will still run all the way through
1701 1703
1702 1704 $ hg debugupgraderepo --run
1703 1705 nothing to do
1704 1706
1705 1707 #if no-rust
1706 1708
1707 1709 $ cat << EOF >> $HGRCPATH
1708 1710 > [storage]
1709 1711 > dirstate-v2.slow-path = allow
1710 1712 > EOF
1711 1713
1712 1714 #endif
1713 1715
1714 1716 Upgrade to dirstate-v2
1715 1717
1716 1718 $ hg debugformat -v --config format.use-dirstate-v2=1 | grep dirstate-v2
1717 1719 dirstate-v2: no yes no
1718 1720 $ hg debugupgraderepo --config format.use-dirstate-v2=1 --run
1719 1721 upgrade will perform the following actions:
1720 1722
1721 1723 requirements
1722 1724 preserved: * (glob)
1723 1725 added: dirstate-v2
1724 1726
1725 1727 dirstate-v2
1726 1728 "hg status" will be faster
1727 1729
1728 1730 no revlogs to process
1729 1731
1730 1732 beginning upgrade...
1731 1733 repository locked and read-only
1732 1734 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1733 1735 (it is safe to interrupt this process any time before data migration completes)
1734 1736 upgrading to dirstate-v2 from v1
1735 1737 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1736 1738 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1737 1739 $ ls .hg/upgradebackup.*/dirstate
1738 1740 .hg/upgradebackup.*/dirstate (glob)
1739 1741 $ hg debugformat -v | grep dirstate-v2
1740 1742 dirstate-v2: yes no no
1741 1743 $ hg status
1742 1744 $ dd bs=12 count=1 if=.hg/dirstate 2> /dev/null
1743 1745 dirstate-v2
1744 1746
1745 1747 Downgrade from dirstate-v2
1746 1748
1747 1749 $ hg debugupgraderepo --run
1748 1750 upgrade will perform the following actions:
1749 1751
1750 1752 requirements
1751 1753 preserved: * (glob)
1752 1754 removed: dirstate-v2
1753 1755
1754 1756 no revlogs to process
1755 1757
1756 1758 beginning upgrade...
1757 1759 repository locked and read-only
1758 1760 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1759 1761 (it is safe to interrupt this process any time before data migration completes)
1760 1762 downgrading from dirstate-v2 to v1
1761 1763 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1762 1764 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1763 1765 $ hg debugformat -v | grep dirstate-v2
1764 1766 dirstate-v2: no no no
1765 1767 $ hg status
1766 1768
1767 1769 $ cd ..
1768 1770
1769 1771 dirstate-v2: upgrade and downgrade from and empty repository:
1770 1772 -------------------------------------------------------------
1771 1773
1772 1774 $ hg init --config format.use-dirstate-v2=no dirstate-v2-empty
1773 1775 $ cd dirstate-v2-empty
1774 1776 $ hg debugformat | grep dirstate-v2
1775 1777 dirstate-v2: no
1776 1778
1777 1779 upgrade
1778 1780
1779 1781 $ hg debugupgraderepo --run --config format.use-dirstate-v2=yes
1780 1782 upgrade will perform the following actions:
1781 1783
1782 1784 requirements
1783 1785 preserved: * (glob)
1784 1786 added: dirstate-v2
1785 1787
1786 1788 dirstate-v2
1787 1789 "hg status" will be faster
1788 1790
1789 1791 no revlogs to process
1790 1792
1791 1793 beginning upgrade...
1792 1794 repository locked and read-only
1793 1795 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1794 1796 (it is safe to interrupt this process any time before data migration completes)
1795 1797 upgrading to dirstate-v2 from v1
1796 1798 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1797 1799 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1798 1800 $ hg debugformat | grep dirstate-v2
1799 1801 dirstate-v2: yes
1800 1802
1801 1803 downgrade
1802 1804
1803 1805 $ hg debugupgraderepo --run --config format.use-dirstate-v2=no
1804 1806 upgrade will perform the following actions:
1805 1807
1806 1808 requirements
1807 1809 preserved: * (glob)
1808 1810 removed: dirstate-v2
1809 1811
1810 1812 no revlogs to process
1811 1813
1812 1814 beginning upgrade...
1813 1815 repository locked and read-only
1814 1816 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1815 1817 (it is safe to interrupt this process any time before data migration completes)
1816 1818 downgrading from dirstate-v2 to v1
1817 1819 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1818 1820 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1819 1821 $ hg debugformat | grep dirstate-v2
1820 1822 dirstate-v2: no
1821 1823
1822 1824 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now