##// END OF EJS Templates
compression: display compression level in debugformat...
marmoute -
r42212:d7e751ec default
parent child Browse files
Show More
@@ -1,916 +1,949 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import stat
10 import stat
11
11
12 from .i18n import _
12 from .i18n import _
13 from . import (
13 from . import (
14 changelog,
14 changelog,
15 error,
15 error,
16 filelog,
16 filelog,
17 hg,
17 hg,
18 localrepo,
18 localrepo,
19 manifest,
19 manifest,
20 pycompat,
20 pycompat,
21 revlog,
21 revlog,
22 scmutil,
22 scmutil,
23 util,
23 util,
24 vfs as vfsmod,
24 vfs as vfsmod,
25 )
25 )
26
26
27 def requiredsourcerequirements(repo):
27 def requiredsourcerequirements(repo):
28 """Obtain requirements required to be present to upgrade a repo.
28 """Obtain requirements required to be present to upgrade a repo.
29
29
30 An upgrade will not be allowed if the repository doesn't have the
30 An upgrade will not be allowed if the repository doesn't have the
31 requirements returned by this function.
31 requirements returned by this function.
32 """
32 """
33 return {
33 return {
34 # Introduced in Mercurial 0.9.2.
34 # Introduced in Mercurial 0.9.2.
35 'revlogv1',
35 'revlogv1',
36 # Introduced in Mercurial 0.9.2.
36 # Introduced in Mercurial 0.9.2.
37 'store',
37 'store',
38 }
38 }
39
39
40 def blocksourcerequirements(repo):
40 def blocksourcerequirements(repo):
41 """Obtain requirements that will prevent an upgrade from occurring.
41 """Obtain requirements that will prevent an upgrade from occurring.
42
42
43 An upgrade cannot be performed if the source repository contains a
43 An upgrade cannot be performed if the source repository contains a
44 requirements in the returned set.
44 requirements in the returned set.
45 """
45 """
46 return {
46 return {
47 # The upgrade code does not yet support these experimental features.
47 # The upgrade code does not yet support these experimental features.
48 # This is an artificial limitation.
48 # This is an artificial limitation.
49 'treemanifest',
49 'treemanifest',
50 # This was a precursor to generaldelta and was never enabled by default.
50 # This was a precursor to generaldelta and was never enabled by default.
51 # It should (hopefully) not exist in the wild.
51 # It should (hopefully) not exist in the wild.
52 'parentdelta',
52 'parentdelta',
53 # Upgrade should operate on the actual store, not the shared link.
53 # Upgrade should operate on the actual store, not the shared link.
54 'shared',
54 'shared',
55 }
55 }
56
56
57 def supportremovedrequirements(repo):
57 def supportremovedrequirements(repo):
58 """Obtain requirements that can be removed during an upgrade.
58 """Obtain requirements that can be removed during an upgrade.
59
59
60 If an upgrade were to create a repository that dropped a requirement,
60 If an upgrade were to create a repository that dropped a requirement,
61 the dropped requirement must appear in the returned set for the upgrade
61 the dropped requirement must appear in the returned set for the upgrade
62 to be allowed.
62 to be allowed.
63 """
63 """
64 return {
64 return {
65 localrepo.SPARSEREVLOG_REQUIREMENT,
65 localrepo.SPARSEREVLOG_REQUIREMENT,
66 }
66 }
67
67
68 def supporteddestrequirements(repo):
68 def supporteddestrequirements(repo):
69 """Obtain requirements that upgrade supports in the destination.
69 """Obtain requirements that upgrade supports in the destination.
70
70
71 If the result of the upgrade would create requirements not in this set,
71 If the result of the upgrade would create requirements not in this set,
72 the upgrade is disallowed.
72 the upgrade is disallowed.
73
73
74 Extensions should monkeypatch this to add their custom requirements.
74 Extensions should monkeypatch this to add their custom requirements.
75 """
75 """
76 return {
76 return {
77 'dotencode',
77 'dotencode',
78 'fncache',
78 'fncache',
79 'generaldelta',
79 'generaldelta',
80 'revlogv1',
80 'revlogv1',
81 'store',
81 'store',
82 localrepo.SPARSEREVLOG_REQUIREMENT,
82 localrepo.SPARSEREVLOG_REQUIREMENT,
83 }
83 }
84
84
85 def allowednewrequirements(repo):
85 def allowednewrequirements(repo):
86 """Obtain requirements that can be added to a repository during upgrade.
86 """Obtain requirements that can be added to a repository during upgrade.
87
87
88 This is used to disallow proposed requirements from being added when
88 This is used to disallow proposed requirements from being added when
89 they weren't present before.
89 they weren't present before.
90
90
91 We use a list of allowed requirement additions instead of a list of known
91 We use a list of allowed requirement additions instead of a list of known
92 bad additions because the whitelist approach is safer and will prevent
92 bad additions because the whitelist approach is safer and will prevent
93 future, unknown requirements from accidentally being added.
93 future, unknown requirements from accidentally being added.
94 """
94 """
95 return {
95 return {
96 'dotencode',
96 'dotencode',
97 'fncache',
97 'fncache',
98 'generaldelta',
98 'generaldelta',
99 localrepo.SPARSEREVLOG_REQUIREMENT,
99 localrepo.SPARSEREVLOG_REQUIREMENT,
100 }
100 }
101
101
102 def preservedrequirements(repo):
102 def preservedrequirements(repo):
103 return set()
103 return set()
104
104
105 deficiency = 'deficiency'
105 deficiency = 'deficiency'
106 optimisation = 'optimization'
106 optimisation = 'optimization'
107
107
108 class improvement(object):
108 class improvement(object):
109 """Represents an improvement that can be made as part of an upgrade.
109 """Represents an improvement that can be made as part of an upgrade.
110
110
111 The following attributes are defined on each instance:
111 The following attributes are defined on each instance:
112
112
113 name
113 name
114 Machine-readable string uniquely identifying this improvement. It
114 Machine-readable string uniquely identifying this improvement. It
115 will be mapped to an action later in the upgrade process.
115 will be mapped to an action later in the upgrade process.
116
116
117 type
117 type
118 Either ``deficiency`` or ``optimisation``. A deficiency is an obvious
118 Either ``deficiency`` or ``optimisation``. A deficiency is an obvious
119 problem. An optimization is an action (sometimes optional) that
119 problem. An optimization is an action (sometimes optional) that
120 can be taken to further improve the state of the repository.
120 can be taken to further improve the state of the repository.
121
121
122 description
122 description
123 Message intended for humans explaining the improvement in more detail,
123 Message intended for humans explaining the improvement in more detail,
124 including the implications of it. For ``deficiency`` types, should be
124 including the implications of it. For ``deficiency`` types, should be
125 worded in the present tense. For ``optimisation`` types, should be
125 worded in the present tense. For ``optimisation`` types, should be
126 worded in the future tense.
126 worded in the future tense.
127
127
128 upgrademessage
128 upgrademessage
129 Message intended for humans explaining what an upgrade addressing this
129 Message intended for humans explaining what an upgrade addressing this
130 issue will do. Should be worded in the future tense.
130 issue will do. Should be worded in the future tense.
131 """
131 """
132 def __init__(self, name, type, description, upgrademessage):
132 def __init__(self, name, type, description, upgrademessage):
133 self.name = name
133 self.name = name
134 self.type = type
134 self.type = type
135 self.description = description
135 self.description = description
136 self.upgrademessage = upgrademessage
136 self.upgrademessage = upgrademessage
137
137
138 def __eq__(self, other):
138 def __eq__(self, other):
139 if not isinstance(other, improvement):
139 if not isinstance(other, improvement):
140 # This is what python tell use to do
140 # This is what python tell use to do
141 return NotImplemented
141 return NotImplemented
142 return self.name == other.name
142 return self.name == other.name
143
143
144 def __ne__(self, other):
144 def __ne__(self, other):
145 return not (self == other)
145 return not (self == other)
146
146
147 def __hash__(self):
147 def __hash__(self):
148 return hash(self.name)
148 return hash(self.name)
149
149
150 allformatvariant = []
150 allformatvariant = []
151
151
152 def registerformatvariant(cls):
152 def registerformatvariant(cls):
153 allformatvariant.append(cls)
153 allformatvariant.append(cls)
154 return cls
154 return cls
155
155
156 class formatvariant(improvement):
156 class formatvariant(improvement):
157 """an improvement subclass dedicated to repository format"""
157 """an improvement subclass dedicated to repository format"""
158 type = deficiency
158 type = deficiency
159 ### The following attributes should be defined for each class:
159 ### The following attributes should be defined for each class:
160
160
161 # machine-readable string uniquely identifying this improvement. it will be
161 # machine-readable string uniquely identifying this improvement. it will be
162 # mapped to an action later in the upgrade process.
162 # mapped to an action later in the upgrade process.
163 name = None
163 name = None
164
164
165 # message intended for humans explaining the improvement in more detail,
165 # message intended for humans explaining the improvement in more detail,
166 # including the implications of it ``deficiency`` types, should be worded
166 # including the implications of it ``deficiency`` types, should be worded
167 # in the present tense.
167 # in the present tense.
168 description = None
168 description = None
169
169
170 # message intended for humans explaining what an upgrade addressing this
170 # message intended for humans explaining what an upgrade addressing this
171 # issue will do. should be worded in the future tense.
171 # issue will do. should be worded in the future tense.
172 upgrademessage = None
172 upgrademessage = None
173
173
174 # value of current Mercurial default for new repository
174 # value of current Mercurial default for new repository
175 default = None
175 default = None
176
176
177 def __init__(self):
177 def __init__(self):
178 raise NotImplementedError()
178 raise NotImplementedError()
179
179
180 @staticmethod
180 @staticmethod
181 def fromrepo(repo):
181 def fromrepo(repo):
182 """current value of the variant in the repository"""
182 """current value of the variant in the repository"""
183 raise NotImplementedError()
183 raise NotImplementedError()
184
184
185 @staticmethod
185 @staticmethod
186 def fromconfig(repo):
186 def fromconfig(repo):
187 """current value of the variant in the configuration"""
187 """current value of the variant in the configuration"""
188 raise NotImplementedError()
188 raise NotImplementedError()
189
189
190 class requirementformatvariant(formatvariant):
190 class requirementformatvariant(formatvariant):
191 """formatvariant based on a 'requirement' name.
191 """formatvariant based on a 'requirement' name.
192
192
193 Many format variant are controlled by a 'requirement'. We define a small
193 Many format variant are controlled by a 'requirement'. We define a small
194 subclass to factor the code.
194 subclass to factor the code.
195 """
195 """
196
196
197 # the requirement that control this format variant
197 # the requirement that control this format variant
198 _requirement = None
198 _requirement = None
199
199
200 @staticmethod
200 @staticmethod
201 def _newreporequirements(ui):
201 def _newreporequirements(ui):
202 return localrepo.newreporequirements(
202 return localrepo.newreporequirements(
203 ui, localrepo.defaultcreateopts(ui))
203 ui, localrepo.defaultcreateopts(ui))
204
204
205 @classmethod
205 @classmethod
206 def fromrepo(cls, repo):
206 def fromrepo(cls, repo):
207 assert cls._requirement is not None
207 assert cls._requirement is not None
208 return cls._requirement in repo.requirements
208 return cls._requirement in repo.requirements
209
209
210 @classmethod
210 @classmethod
211 def fromconfig(cls, repo):
211 def fromconfig(cls, repo):
212 assert cls._requirement is not None
212 assert cls._requirement is not None
213 return cls._requirement in cls._newreporequirements(repo.ui)
213 return cls._requirement in cls._newreporequirements(repo.ui)
214
214
215 @registerformatvariant
215 @registerformatvariant
216 class fncache(requirementformatvariant):
216 class fncache(requirementformatvariant):
217 name = 'fncache'
217 name = 'fncache'
218
218
219 _requirement = 'fncache'
219 _requirement = 'fncache'
220
220
221 default = True
221 default = True
222
222
223 description = _('long and reserved filenames may not work correctly; '
223 description = _('long and reserved filenames may not work correctly; '
224 'repository performance is sub-optimal')
224 'repository performance is sub-optimal')
225
225
226 upgrademessage = _('repository will be more resilient to storing '
226 upgrademessage = _('repository will be more resilient to storing '
227 'certain paths and performance of certain '
227 'certain paths and performance of certain '
228 'operations should be improved')
228 'operations should be improved')
229
229
230 @registerformatvariant
230 @registerformatvariant
231 class dotencode(requirementformatvariant):
231 class dotencode(requirementformatvariant):
232 name = 'dotencode'
232 name = 'dotencode'
233
233
234 _requirement = 'dotencode'
234 _requirement = 'dotencode'
235
235
236 default = True
236 default = True
237
237
238 description = _('storage of filenames beginning with a period or '
238 description = _('storage of filenames beginning with a period or '
239 'space may not work correctly')
239 'space may not work correctly')
240
240
241 upgrademessage = _('repository will be better able to store files '
241 upgrademessage = _('repository will be better able to store files '
242 'beginning with a space or period')
242 'beginning with a space or period')
243
243
244 @registerformatvariant
244 @registerformatvariant
245 class generaldelta(requirementformatvariant):
245 class generaldelta(requirementformatvariant):
246 name = 'generaldelta'
246 name = 'generaldelta'
247
247
248 _requirement = 'generaldelta'
248 _requirement = 'generaldelta'
249
249
250 default = True
250 default = True
251
251
252 description = _('deltas within internal storage are unable to '
252 description = _('deltas within internal storage are unable to '
253 'choose optimal revisions; repository is larger and '
253 'choose optimal revisions; repository is larger and '
254 'slower than it could be; interaction with other '
254 'slower than it could be; interaction with other '
255 'repositories may require extra network and CPU '
255 'repositories may require extra network and CPU '
256 'resources, making "hg push" and "hg pull" slower')
256 'resources, making "hg push" and "hg pull" slower')
257
257
258 upgrademessage = _('repository storage will be able to create '
258 upgrademessage = _('repository storage will be able to create '
259 'optimal deltas; new repository data will be '
259 'optimal deltas; new repository data will be '
260 'smaller and read times should decrease; '
260 'smaller and read times should decrease; '
261 'interacting with other repositories using this '
261 'interacting with other repositories using this '
262 'storage model should require less network and '
262 'storage model should require less network and '
263 'CPU resources, making "hg push" and "hg pull" '
263 'CPU resources, making "hg push" and "hg pull" '
264 'faster')
264 'faster')
265
265
266 @registerformatvariant
266 @registerformatvariant
267 class sparserevlog(requirementformatvariant):
267 class sparserevlog(requirementformatvariant):
268 name = 'sparserevlog'
268 name = 'sparserevlog'
269
269
270 _requirement = localrepo.SPARSEREVLOG_REQUIREMENT
270 _requirement = localrepo.SPARSEREVLOG_REQUIREMENT
271
271
272 default = True
272 default = True
273
273
274 description = _('in order to limit disk reading and memory usage on older '
274 description = _('in order to limit disk reading and memory usage on older '
275 'version, the span of a delta chain from its root to its '
275 'version, the span of a delta chain from its root to its '
276 'end is limited, whatever the relevant data in this span. '
276 'end is limited, whatever the relevant data in this span. '
277 'This can severly limit Mercurial ability to build good '
277 'This can severly limit Mercurial ability to build good '
278 'chain of delta resulting is much more storage space being '
278 'chain of delta resulting is much more storage space being '
279 'taken and limit reusability of on disk delta during '
279 'taken and limit reusability of on disk delta during '
280 'exchange.'
280 'exchange.'
281 )
281 )
282
282
283 upgrademessage = _('Revlog supports delta chain with more unused data '
283 upgrademessage = _('Revlog supports delta chain with more unused data '
284 'between payload. These gaps will be skipped at read '
284 'between payload. These gaps will be skipped at read '
285 'time. This allows for better delta chains, making a '
285 'time. This allows for better delta chains, making a '
286 'better compression and faster exchange with server.')
286 'better compression and faster exchange with server.')
287
287
288 @registerformatvariant
288 @registerformatvariant
289 class removecldeltachain(formatvariant):
289 class removecldeltachain(formatvariant):
290 name = 'plain-cl-delta'
290 name = 'plain-cl-delta'
291
291
292 default = True
292 default = True
293
293
294 description = _('changelog storage is using deltas instead of '
294 description = _('changelog storage is using deltas instead of '
295 'raw entries; changelog reading and any '
295 'raw entries; changelog reading and any '
296 'operation relying on changelog data are slower '
296 'operation relying on changelog data are slower '
297 'than they could be')
297 'than they could be')
298
298
299 upgrademessage = _('changelog storage will be reformated to '
299 upgrademessage = _('changelog storage will be reformated to '
300 'store raw entries; changelog reading will be '
300 'store raw entries; changelog reading will be '
301 'faster; changelog size may be reduced')
301 'faster; changelog size may be reduced')
302
302
303 @staticmethod
303 @staticmethod
304 def fromrepo(repo):
304 def fromrepo(repo):
305 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
305 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
306 # changelogs with deltas.
306 # changelogs with deltas.
307 cl = repo.changelog
307 cl = repo.changelog
308 chainbase = cl.chainbase
308 chainbase = cl.chainbase
309 return all(rev == chainbase(rev) for rev in cl)
309 return all(rev == chainbase(rev) for rev in cl)
310
310
311 @staticmethod
311 @staticmethod
312 def fromconfig(repo):
312 def fromconfig(repo):
313 return True
313 return True
314
314
315 @registerformatvariant
315 @registerformatvariant
316 class compressionengine(formatvariant):
316 class compressionengine(formatvariant):
317 name = 'compression'
317 name = 'compression'
318 default = 'zlib'
318 default = 'zlib'
319
319
320 description = _('Compresion algorithm used to compress data. '
320 description = _('Compresion algorithm used to compress data. '
321 'Some engine are faster than other')
321 'Some engine are faster than other')
322
322
323 upgrademessage = _('revlog content will be recompressed with the new '
323 upgrademessage = _('revlog content will be recompressed with the new '
324 'algorithm.')
324 'algorithm.')
325
325
326 @classmethod
326 @classmethod
327 def fromrepo(cls, repo):
327 def fromrepo(cls, repo):
328 for req in repo.requirements:
328 for req in repo.requirements:
329 if req.startswith('exp-compression-'):
329 if req.startswith('exp-compression-'):
330 return req.split('-', 2)[2]
330 return req.split('-', 2)[2]
331 return 'zlib'
331 return 'zlib'
332
332
333 @classmethod
333 @classmethod
334 def fromconfig(cls, repo):
334 def fromconfig(cls, repo):
335 return repo.ui.config('experimental', 'format.compression')
335 return repo.ui.config('experimental', 'format.compression')
336
336
337 @registerformatvariant
338 class compressionlevel(formatvariant):
339 name = 'compression-level'
340 default = 'default'
341
342 description = _('compression level')
343
344 upgrademessage = _('revlog content will be recompressed')
345
346 @classmethod
347 def fromrepo(cls, repo):
348 comp = compressionengine.fromrepo(repo)
349 level = None
350 if comp == 'zlib':
351 level = repo.ui.configint('storage', 'revlog.zlib.level')
352 elif comp == 'zstd':
353 level = repo.ui.configint('storage', 'revlog.zstd.level')
354 if level is None:
355 return 'default'
356 return bytes(level)
357
358 @classmethod
359 def fromconfig(cls, repo):
360 comp = compressionengine.fromconfig(repo)
361 level = None
362 if comp == 'zlib':
363 level = repo.ui.configint('storage', 'revlog.zlib.level')
364 elif comp == 'zstd':
365 level = repo.ui.configint('storage', 'revlog.zstd.level')
366 if level is None:
367 return 'default'
368 return bytes(level)
369
337 def finddeficiencies(repo):
370 def finddeficiencies(repo):
338 """returns a list of deficiencies that the repo suffer from"""
371 """returns a list of deficiencies that the repo suffer from"""
339 deficiencies = []
372 deficiencies = []
340
373
341 # We could detect lack of revlogv1 and store here, but they were added
374 # We could detect lack of revlogv1 and store here, but they were added
342 # in 0.9.2 and we don't support upgrading repos without these
375 # in 0.9.2 and we don't support upgrading repos without these
343 # requirements, so let's not bother.
376 # requirements, so let's not bother.
344
377
345 for fv in allformatvariant:
378 for fv in allformatvariant:
346 if not fv.fromrepo(repo):
379 if not fv.fromrepo(repo):
347 deficiencies.append(fv)
380 deficiencies.append(fv)
348
381
349 return deficiencies
382 return deficiencies
350
383
351 # search without '-' to support older form on newer client.
384 # search without '-' to support older form on newer client.
352 #
385 #
353 # We don't enforce backward compatibility for debug command so this
386 # We don't enforce backward compatibility for debug command so this
354 # might eventually be dropped. However, having to use two different
387 # might eventually be dropped. However, having to use two different
355 # forms in script when comparing result is anoying enough to add
388 # forms in script when comparing result is anoying enough to add
356 # backward compatibility for a while.
389 # backward compatibility for a while.
357 legacy_opts_map = {
390 legacy_opts_map = {
358 'redeltaparent': 're-delta-parent',
391 'redeltaparent': 're-delta-parent',
359 'redeltamultibase': 're-delta-multibase',
392 'redeltamultibase': 're-delta-multibase',
360 'redeltaall': 're-delta-all',
393 'redeltaall': 're-delta-all',
361 'redeltafulladd': 're-delta-fulladd',
394 'redeltafulladd': 're-delta-fulladd',
362 }
395 }
363
396
364 def findoptimizations(repo):
397 def findoptimizations(repo):
365 """Determine optimisation that could be used during upgrade"""
398 """Determine optimisation that could be used during upgrade"""
366 # These are unconditionally added. There is logic later that figures out
399 # These are unconditionally added. There is logic later that figures out
367 # which ones to apply.
400 # which ones to apply.
368 optimizations = []
401 optimizations = []
369
402
370 optimizations.append(improvement(
403 optimizations.append(improvement(
371 name='re-delta-parent',
404 name='re-delta-parent',
372 type=optimisation,
405 type=optimisation,
373 description=_('deltas within internal storage will be recalculated to '
406 description=_('deltas within internal storage will be recalculated to '
374 'choose an optimal base revision where this was not '
407 'choose an optimal base revision where this was not '
375 'already done; the size of the repository may shrink and '
408 'already done; the size of the repository may shrink and '
376 'various operations may become faster; the first time '
409 'various operations may become faster; the first time '
377 'this optimization is performed could slow down upgrade '
410 'this optimization is performed could slow down upgrade '
378 'execution considerably; subsequent invocations should '
411 'execution considerably; subsequent invocations should '
379 'not run noticeably slower'),
412 'not run noticeably slower'),
380 upgrademessage=_('deltas within internal storage will choose a new '
413 upgrademessage=_('deltas within internal storage will choose a new '
381 'base revision if needed')))
414 'base revision if needed')))
382
415
383 optimizations.append(improvement(
416 optimizations.append(improvement(
384 name='re-delta-multibase',
417 name='re-delta-multibase',
385 type=optimisation,
418 type=optimisation,
386 description=_('deltas within internal storage will be recalculated '
419 description=_('deltas within internal storage will be recalculated '
387 'against multiple base revision and the smallest '
420 'against multiple base revision and the smallest '
388 'difference will be used; the size of the repository may '
421 'difference will be used; the size of the repository may '
389 'shrink significantly when there are many merges; this '
422 'shrink significantly when there are many merges; this '
390 'optimization will slow down execution in proportion to '
423 'optimization will slow down execution in proportion to '
391 'the number of merges in the repository and the amount '
424 'the number of merges in the repository and the amount '
392 'of files in the repository; this slow down should not '
425 'of files in the repository; this slow down should not '
393 'be significant unless there are tens of thousands of '
426 'be significant unless there are tens of thousands of '
394 'files and thousands of merges'),
427 'files and thousands of merges'),
395 upgrademessage=_('deltas within internal storage will choose an '
428 upgrademessage=_('deltas within internal storage will choose an '
396 'optimal delta by computing deltas against multiple '
429 'optimal delta by computing deltas against multiple '
397 'parents; may slow down execution time '
430 'parents; may slow down execution time '
398 'significantly')))
431 'significantly')))
399
432
400 optimizations.append(improvement(
433 optimizations.append(improvement(
401 name='re-delta-all',
434 name='re-delta-all',
402 type=optimisation,
435 type=optimisation,
403 description=_('deltas within internal storage will always be '
436 description=_('deltas within internal storage will always be '
404 'recalculated without reusing prior deltas; this will '
437 'recalculated without reusing prior deltas; this will '
405 'likely make execution run several times slower; this '
438 'likely make execution run several times slower; this '
406 'optimization is typically not needed'),
439 'optimization is typically not needed'),
407 upgrademessage=_('deltas within internal storage will be fully '
440 upgrademessage=_('deltas within internal storage will be fully '
408 'recomputed; this will likely drastically slow down '
441 'recomputed; this will likely drastically slow down '
409 'execution time')))
442 'execution time')))
410
443
411 optimizations.append(improvement(
444 optimizations.append(improvement(
412 name='re-delta-fulladd',
445 name='re-delta-fulladd',
413 type=optimisation,
446 type=optimisation,
414 description=_('every revision will be re-added as if it was new '
447 description=_('every revision will be re-added as if it was new '
415 'content. It will go through the full storage '
448 'content. It will go through the full storage '
416 'mechanism giving extensions a chance to process it '
449 'mechanism giving extensions a chance to process it '
417 '(eg. lfs). This is similar to "re-delta-all" but even '
450 '(eg. lfs). This is similar to "re-delta-all" but even '
418 'slower since more logic is involved.'),
451 'slower since more logic is involved.'),
419 upgrademessage=_('each revision will be added as new content to the '
452 upgrademessage=_('each revision will be added as new content to the '
420 'internal storage; this will likely drastically slow '
453 'internal storage; this will likely drastically slow '
421 'down execution time, but some extensions might need '
454 'down execution time, but some extensions might need '
422 'it')))
455 'it')))
423
456
424 return optimizations
457 return optimizations
425
458
426 def determineactions(repo, deficiencies, sourcereqs, destreqs):
459 def determineactions(repo, deficiencies, sourcereqs, destreqs):
427 """Determine upgrade actions that will be performed.
460 """Determine upgrade actions that will be performed.
428
461
429 Given a list of improvements as returned by ``finddeficiencies`` and
462 Given a list of improvements as returned by ``finddeficiencies`` and
430 ``findoptimizations``, determine the list of upgrade actions that
463 ``findoptimizations``, determine the list of upgrade actions that
431 will be performed.
464 will be performed.
432
465
433 The role of this function is to filter improvements if needed, apply
466 The role of this function is to filter improvements if needed, apply
434 recommended optimizations from the improvements list that make sense,
467 recommended optimizations from the improvements list that make sense,
435 etc.
468 etc.
436
469
437 Returns a list of action names.
470 Returns a list of action names.
438 """
471 """
439 newactions = []
472 newactions = []
440
473
441 knownreqs = supporteddestrequirements(repo)
474 knownreqs = supporteddestrequirements(repo)
442
475
443 for d in deficiencies:
476 for d in deficiencies:
444 name = d.name
477 name = d.name
445
478
446 # If the action is a requirement that doesn't show up in the
479 # If the action is a requirement that doesn't show up in the
447 # destination requirements, prune the action.
480 # destination requirements, prune the action.
448 if name in knownreqs and name not in destreqs:
481 if name in knownreqs and name not in destreqs:
449 continue
482 continue
450
483
451 newactions.append(d)
484 newactions.append(d)
452
485
453 # FUTURE consider adding some optimizations here for certain transitions.
486 # FUTURE consider adding some optimizations here for certain transitions.
454 # e.g. adding generaldelta could schedule parent redeltas.
487 # e.g. adding generaldelta could schedule parent redeltas.
455
488
456 return newactions
489 return newactions
457
490
458 def _revlogfrompath(repo, path):
491 def _revlogfrompath(repo, path):
459 """Obtain a revlog from a repo path.
492 """Obtain a revlog from a repo path.
460
493
461 An instance of the appropriate class is returned.
494 An instance of the appropriate class is returned.
462 """
495 """
463 if path == '00changelog.i':
496 if path == '00changelog.i':
464 return changelog.changelog(repo.svfs)
497 return changelog.changelog(repo.svfs)
465 elif path.endswith('00manifest.i'):
498 elif path.endswith('00manifest.i'):
466 mandir = path[:-len('00manifest.i')]
499 mandir = path[:-len('00manifest.i')]
467 return manifest.manifestrevlog(repo.svfs, tree=mandir)
500 return manifest.manifestrevlog(repo.svfs, tree=mandir)
468 else:
501 else:
469 #reverse of "/".join(("data", path + ".i"))
502 #reverse of "/".join(("data", path + ".i"))
470 return filelog.filelog(repo.svfs, path[5:-2])
503 return filelog.filelog(repo.svfs, path[5:-2])
471
504
472 def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, forcedeltabothparents):
505 def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, forcedeltabothparents):
473 """Copy revlogs between 2 repos."""
506 """Copy revlogs between 2 repos."""
474 revcount = 0
507 revcount = 0
475 srcsize = 0
508 srcsize = 0
476 srcrawsize = 0
509 srcrawsize = 0
477 dstsize = 0
510 dstsize = 0
478 fcount = 0
511 fcount = 0
479 frevcount = 0
512 frevcount = 0
480 fsrcsize = 0
513 fsrcsize = 0
481 frawsize = 0
514 frawsize = 0
482 fdstsize = 0
515 fdstsize = 0
483 mcount = 0
516 mcount = 0
484 mrevcount = 0
517 mrevcount = 0
485 msrcsize = 0
518 msrcsize = 0
486 mrawsize = 0
519 mrawsize = 0
487 mdstsize = 0
520 mdstsize = 0
488 crevcount = 0
521 crevcount = 0
489 csrcsize = 0
522 csrcsize = 0
490 crawsize = 0
523 crawsize = 0
491 cdstsize = 0
524 cdstsize = 0
492
525
493 # Perform a pass to collect metadata. This validates we can open all
526 # Perform a pass to collect metadata. This validates we can open all
494 # source files and allows a unified progress bar to be displayed.
527 # source files and allows a unified progress bar to be displayed.
495 for unencoded, encoded, size in srcrepo.store.walk():
528 for unencoded, encoded, size in srcrepo.store.walk():
496 if unencoded.endswith('.d'):
529 if unencoded.endswith('.d'):
497 continue
530 continue
498
531
499 rl = _revlogfrompath(srcrepo, unencoded)
532 rl = _revlogfrompath(srcrepo, unencoded)
500
533
501 info = rl.storageinfo(exclusivefiles=True, revisionscount=True,
534 info = rl.storageinfo(exclusivefiles=True, revisionscount=True,
502 trackedsize=True, storedsize=True)
535 trackedsize=True, storedsize=True)
503
536
504 revcount += info['revisionscount'] or 0
537 revcount += info['revisionscount'] or 0
505 datasize = info['storedsize'] or 0
538 datasize = info['storedsize'] or 0
506 rawsize = info['trackedsize'] or 0
539 rawsize = info['trackedsize'] or 0
507
540
508 srcsize += datasize
541 srcsize += datasize
509 srcrawsize += rawsize
542 srcrawsize += rawsize
510
543
511 # This is for the separate progress bars.
544 # This is for the separate progress bars.
512 if isinstance(rl, changelog.changelog):
545 if isinstance(rl, changelog.changelog):
513 crevcount += len(rl)
546 crevcount += len(rl)
514 csrcsize += datasize
547 csrcsize += datasize
515 crawsize += rawsize
548 crawsize += rawsize
516 elif isinstance(rl, manifest.manifestrevlog):
549 elif isinstance(rl, manifest.manifestrevlog):
517 mcount += 1
550 mcount += 1
518 mrevcount += len(rl)
551 mrevcount += len(rl)
519 msrcsize += datasize
552 msrcsize += datasize
520 mrawsize += rawsize
553 mrawsize += rawsize
521 elif isinstance(rl, filelog.filelog):
554 elif isinstance(rl, filelog.filelog):
522 fcount += 1
555 fcount += 1
523 frevcount += len(rl)
556 frevcount += len(rl)
524 fsrcsize += datasize
557 fsrcsize += datasize
525 frawsize += rawsize
558 frawsize += rawsize
526 else:
559 else:
527 error.ProgrammingError('unknown revlog type')
560 error.ProgrammingError('unknown revlog type')
528
561
529 if not revcount:
562 if not revcount:
530 return
563 return
531
564
532 ui.write(_('migrating %d total revisions (%d in filelogs, %d in manifests, '
565 ui.write(_('migrating %d total revisions (%d in filelogs, %d in manifests, '
533 '%d in changelog)\n') %
566 '%d in changelog)\n') %
534 (revcount, frevcount, mrevcount, crevcount))
567 (revcount, frevcount, mrevcount, crevcount))
535 ui.write(_('migrating %s in store; %s tracked data\n') % (
568 ui.write(_('migrating %s in store; %s tracked data\n') % (
536 (util.bytecount(srcsize), util.bytecount(srcrawsize))))
569 (util.bytecount(srcsize), util.bytecount(srcrawsize))))
537
570
538 # Used to keep track of progress.
571 # Used to keep track of progress.
539 progress = None
572 progress = None
540 def oncopiedrevision(rl, rev, node):
573 def oncopiedrevision(rl, rev, node):
541 progress.increment()
574 progress.increment()
542
575
543 # Do the actual copying.
576 # Do the actual copying.
544 # FUTURE this operation can be farmed off to worker processes.
577 # FUTURE this operation can be farmed off to worker processes.
545 seen = set()
578 seen = set()
546 for unencoded, encoded, size in srcrepo.store.walk():
579 for unencoded, encoded, size in srcrepo.store.walk():
547 if unencoded.endswith('.d'):
580 if unencoded.endswith('.d'):
548 continue
581 continue
549
582
550 oldrl = _revlogfrompath(srcrepo, unencoded)
583 oldrl = _revlogfrompath(srcrepo, unencoded)
551 newrl = _revlogfrompath(dstrepo, unencoded)
584 newrl = _revlogfrompath(dstrepo, unencoded)
552
585
553 if isinstance(oldrl, changelog.changelog) and 'c' not in seen:
586 if isinstance(oldrl, changelog.changelog) and 'c' not in seen:
554 ui.write(_('finished migrating %d manifest revisions across %d '
587 ui.write(_('finished migrating %d manifest revisions across %d '
555 'manifests; change in size: %s\n') %
588 'manifests; change in size: %s\n') %
556 (mrevcount, mcount, util.bytecount(mdstsize - msrcsize)))
589 (mrevcount, mcount, util.bytecount(mdstsize - msrcsize)))
557
590
558 ui.write(_('migrating changelog containing %d revisions '
591 ui.write(_('migrating changelog containing %d revisions '
559 '(%s in store; %s tracked data)\n') %
592 '(%s in store; %s tracked data)\n') %
560 (crevcount, util.bytecount(csrcsize),
593 (crevcount, util.bytecount(csrcsize),
561 util.bytecount(crawsize)))
594 util.bytecount(crawsize)))
562 seen.add('c')
595 seen.add('c')
563 progress = srcrepo.ui.makeprogress(_('changelog revisions'),
596 progress = srcrepo.ui.makeprogress(_('changelog revisions'),
564 total=crevcount)
597 total=crevcount)
565 elif isinstance(oldrl, manifest.manifestrevlog) and 'm' not in seen:
598 elif isinstance(oldrl, manifest.manifestrevlog) and 'm' not in seen:
566 ui.write(_('finished migrating %d filelog revisions across %d '
599 ui.write(_('finished migrating %d filelog revisions across %d '
567 'filelogs; change in size: %s\n') %
600 'filelogs; change in size: %s\n') %
568 (frevcount, fcount, util.bytecount(fdstsize - fsrcsize)))
601 (frevcount, fcount, util.bytecount(fdstsize - fsrcsize)))
569
602
570 ui.write(_('migrating %d manifests containing %d revisions '
603 ui.write(_('migrating %d manifests containing %d revisions '
571 '(%s in store; %s tracked data)\n') %
604 '(%s in store; %s tracked data)\n') %
572 (mcount, mrevcount, util.bytecount(msrcsize),
605 (mcount, mrevcount, util.bytecount(msrcsize),
573 util.bytecount(mrawsize)))
606 util.bytecount(mrawsize)))
574 seen.add('m')
607 seen.add('m')
575 if progress:
608 if progress:
576 progress.complete()
609 progress.complete()
577 progress = srcrepo.ui.makeprogress(_('manifest revisions'),
610 progress = srcrepo.ui.makeprogress(_('manifest revisions'),
578 total=mrevcount)
611 total=mrevcount)
579 elif 'f' not in seen:
612 elif 'f' not in seen:
580 ui.write(_('migrating %d filelogs containing %d revisions '
613 ui.write(_('migrating %d filelogs containing %d revisions '
581 '(%s in store; %s tracked data)\n') %
614 '(%s in store; %s tracked data)\n') %
582 (fcount, frevcount, util.bytecount(fsrcsize),
615 (fcount, frevcount, util.bytecount(fsrcsize),
583 util.bytecount(frawsize)))
616 util.bytecount(frawsize)))
584 seen.add('f')
617 seen.add('f')
585 if progress:
618 if progress:
586 progress.complete()
619 progress.complete()
587 progress = srcrepo.ui.makeprogress(_('file revisions'),
620 progress = srcrepo.ui.makeprogress(_('file revisions'),
588 total=frevcount)
621 total=frevcount)
589
622
590
623
591 ui.note(_('cloning %d revisions from %s\n') % (len(oldrl), unencoded))
624 ui.note(_('cloning %d revisions from %s\n') % (len(oldrl), unencoded))
592 oldrl.clone(tr, newrl, addrevisioncb=oncopiedrevision,
625 oldrl.clone(tr, newrl, addrevisioncb=oncopiedrevision,
593 deltareuse=deltareuse,
626 deltareuse=deltareuse,
594 forcedeltabothparents=forcedeltabothparents)
627 forcedeltabothparents=forcedeltabothparents)
595
628
596 info = newrl.storageinfo(storedsize=True)
629 info = newrl.storageinfo(storedsize=True)
597 datasize = info['storedsize'] or 0
630 datasize = info['storedsize'] or 0
598
631
599 dstsize += datasize
632 dstsize += datasize
600
633
601 if isinstance(newrl, changelog.changelog):
634 if isinstance(newrl, changelog.changelog):
602 cdstsize += datasize
635 cdstsize += datasize
603 elif isinstance(newrl, manifest.manifestrevlog):
636 elif isinstance(newrl, manifest.manifestrevlog):
604 mdstsize += datasize
637 mdstsize += datasize
605 else:
638 else:
606 fdstsize += datasize
639 fdstsize += datasize
607
640
608 progress.complete()
641 progress.complete()
609
642
610 ui.write(_('finished migrating %d changelog revisions; change in size: '
643 ui.write(_('finished migrating %d changelog revisions; change in size: '
611 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize)))
644 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize)))
612
645
613 ui.write(_('finished migrating %d total revisions; total change in store '
646 ui.write(_('finished migrating %d total revisions; total change in store '
614 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize)))
647 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize)))
615
648
616 def _filterstorefile(srcrepo, dstrepo, requirements, path, mode, st):
649 def _filterstorefile(srcrepo, dstrepo, requirements, path, mode, st):
617 """Determine whether to copy a store file during upgrade.
650 """Determine whether to copy a store file during upgrade.
618
651
619 This function is called when migrating store files from ``srcrepo`` to
652 This function is called when migrating store files from ``srcrepo`` to
620 ``dstrepo`` as part of upgrading a repository.
653 ``dstrepo`` as part of upgrading a repository.
621
654
622 Args:
655 Args:
623 srcrepo: repo we are copying from
656 srcrepo: repo we are copying from
624 dstrepo: repo we are copying to
657 dstrepo: repo we are copying to
625 requirements: set of requirements for ``dstrepo``
658 requirements: set of requirements for ``dstrepo``
626 path: store file being examined
659 path: store file being examined
627 mode: the ``ST_MODE`` file type of ``path``
660 mode: the ``ST_MODE`` file type of ``path``
628 st: ``stat`` data structure for ``path``
661 st: ``stat`` data structure for ``path``
629
662
630 Function should return ``True`` if the file is to be copied.
663 Function should return ``True`` if the file is to be copied.
631 """
664 """
632 # Skip revlogs.
665 # Skip revlogs.
633 if path.endswith(('.i', '.d')):
666 if path.endswith(('.i', '.d')):
634 return False
667 return False
635 # Skip transaction related files.
668 # Skip transaction related files.
636 if path.startswith('undo'):
669 if path.startswith('undo'):
637 return False
670 return False
638 # Only copy regular files.
671 # Only copy regular files.
639 if mode != stat.S_IFREG:
672 if mode != stat.S_IFREG:
640 return False
673 return False
641 # Skip other skipped files.
674 # Skip other skipped files.
642 if path in ('lock', 'fncache'):
675 if path in ('lock', 'fncache'):
643 return False
676 return False
644
677
645 return True
678 return True
646
679
647 def _finishdatamigration(ui, srcrepo, dstrepo, requirements):
680 def _finishdatamigration(ui, srcrepo, dstrepo, requirements):
648 """Hook point for extensions to perform additional actions during upgrade.
681 """Hook point for extensions to perform additional actions during upgrade.
649
682
650 This function is called after revlogs and store files have been copied but
683 This function is called after revlogs and store files have been copied but
651 before the new store is swapped into the original location.
684 before the new store is swapped into the original location.
652 """
685 """
653
686
654 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions):
687 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions):
655 """Do the low-level work of upgrading a repository.
688 """Do the low-level work of upgrading a repository.
656
689
657 The upgrade is effectively performed as a copy between a source
690 The upgrade is effectively performed as a copy between a source
658 repository and a temporary destination repository.
691 repository and a temporary destination repository.
659
692
660 The source repository is unmodified for as long as possible so the
693 The source repository is unmodified for as long as possible so the
661 upgrade can abort at any time without causing loss of service for
694 upgrade can abort at any time without causing loss of service for
662 readers and without corrupting the source repository.
695 readers and without corrupting the source repository.
663 """
696 """
664 assert srcrepo.currentwlock()
697 assert srcrepo.currentwlock()
665 assert dstrepo.currentwlock()
698 assert dstrepo.currentwlock()
666
699
667 ui.write(_('(it is safe to interrupt this process any time before '
700 ui.write(_('(it is safe to interrupt this process any time before '
668 'data migration completes)\n'))
701 'data migration completes)\n'))
669
702
670 if 're-delta-all' in actions:
703 if 're-delta-all' in actions:
671 deltareuse = revlog.revlog.DELTAREUSENEVER
704 deltareuse = revlog.revlog.DELTAREUSENEVER
672 elif 're-delta-parent' in actions:
705 elif 're-delta-parent' in actions:
673 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
706 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
674 elif 're-delta-multibase' in actions:
707 elif 're-delta-multibase' in actions:
675 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
708 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
676 elif 're-delta-fulladd' in actions:
709 elif 're-delta-fulladd' in actions:
677 deltareuse = revlog.revlog.DELTAREUSEFULLADD
710 deltareuse = revlog.revlog.DELTAREUSEFULLADD
678 else:
711 else:
679 deltareuse = revlog.revlog.DELTAREUSEALWAYS
712 deltareuse = revlog.revlog.DELTAREUSEALWAYS
680
713
681 with dstrepo.transaction('upgrade') as tr:
714 with dstrepo.transaction('upgrade') as tr:
682 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse,
715 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse,
683 're-delta-multibase' in actions)
716 're-delta-multibase' in actions)
684
717
685 # Now copy other files in the store directory.
718 # Now copy other files in the store directory.
686 # The sorted() makes execution deterministic.
719 # The sorted() makes execution deterministic.
687 for p, kind, st in sorted(srcrepo.store.vfs.readdir('', stat=True)):
720 for p, kind, st in sorted(srcrepo.store.vfs.readdir('', stat=True)):
688 if not _filterstorefile(srcrepo, dstrepo, requirements,
721 if not _filterstorefile(srcrepo, dstrepo, requirements,
689 p, kind, st):
722 p, kind, st):
690 continue
723 continue
691
724
692 srcrepo.ui.write(_('copying %s\n') % p)
725 srcrepo.ui.write(_('copying %s\n') % p)
693 src = srcrepo.store.rawvfs.join(p)
726 src = srcrepo.store.rawvfs.join(p)
694 dst = dstrepo.store.rawvfs.join(p)
727 dst = dstrepo.store.rawvfs.join(p)
695 util.copyfile(src, dst, copystat=True)
728 util.copyfile(src, dst, copystat=True)
696
729
697 _finishdatamigration(ui, srcrepo, dstrepo, requirements)
730 _finishdatamigration(ui, srcrepo, dstrepo, requirements)
698
731
699 ui.write(_('data fully migrated to temporary repository\n'))
732 ui.write(_('data fully migrated to temporary repository\n'))
700
733
701 backuppath = pycompat.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path)
734 backuppath = pycompat.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path)
702 backupvfs = vfsmod.vfs(backuppath)
735 backupvfs = vfsmod.vfs(backuppath)
703
736
704 # Make a backup of requires file first, as it is the first to be modified.
737 # Make a backup of requires file first, as it is the first to be modified.
705 util.copyfile(srcrepo.vfs.join('requires'), backupvfs.join('requires'))
738 util.copyfile(srcrepo.vfs.join('requires'), backupvfs.join('requires'))
706
739
707 # We install an arbitrary requirement that clients must not support
740 # We install an arbitrary requirement that clients must not support
708 # as a mechanism to lock out new clients during the data swap. This is
741 # as a mechanism to lock out new clients during the data swap. This is
709 # better than allowing a client to continue while the repository is in
742 # better than allowing a client to continue while the repository is in
710 # an inconsistent state.
743 # an inconsistent state.
711 ui.write(_('marking source repository as being upgraded; clients will be '
744 ui.write(_('marking source repository as being upgraded; clients will be '
712 'unable to read from repository\n'))
745 'unable to read from repository\n'))
713 scmutil.writerequires(srcrepo.vfs,
746 scmutil.writerequires(srcrepo.vfs,
714 srcrepo.requirements | {'upgradeinprogress'})
747 srcrepo.requirements | {'upgradeinprogress'})
715
748
716 ui.write(_('starting in-place swap of repository data\n'))
749 ui.write(_('starting in-place swap of repository data\n'))
717 ui.write(_('replaced files will be backed up at %s\n') %
750 ui.write(_('replaced files will be backed up at %s\n') %
718 backuppath)
751 backuppath)
719
752
720 # Now swap in the new store directory. Doing it as a rename should make
753 # Now swap in the new store directory. Doing it as a rename should make
721 # the operation nearly instantaneous and atomic (at least in well-behaved
754 # the operation nearly instantaneous and atomic (at least in well-behaved
722 # environments).
755 # environments).
723 ui.write(_('replacing store...\n'))
756 ui.write(_('replacing store...\n'))
724 tstart = util.timer()
757 tstart = util.timer()
725 util.rename(srcrepo.spath, backupvfs.join('store'))
758 util.rename(srcrepo.spath, backupvfs.join('store'))
726 util.rename(dstrepo.spath, srcrepo.spath)
759 util.rename(dstrepo.spath, srcrepo.spath)
727 elapsed = util.timer() - tstart
760 elapsed = util.timer() - tstart
728 ui.write(_('store replacement complete; repository was inconsistent for '
761 ui.write(_('store replacement complete; repository was inconsistent for '
729 '%0.1fs\n') % elapsed)
762 '%0.1fs\n') % elapsed)
730
763
731 # We first write the requirements file. Any new requirements will lock
764 # We first write the requirements file. Any new requirements will lock
732 # out legacy clients.
765 # out legacy clients.
733 ui.write(_('finalizing requirements file and making repository readable '
766 ui.write(_('finalizing requirements file and making repository readable '
734 'again\n'))
767 'again\n'))
735 scmutil.writerequires(srcrepo.vfs, requirements)
768 scmutil.writerequires(srcrepo.vfs, requirements)
736
769
737 # The lock file from the old store won't be removed because nothing has a
770 # The lock file from the old store won't be removed because nothing has a
738 # reference to its new location. So clean it up manually. Alternatively, we
771 # reference to its new location. So clean it up manually. Alternatively, we
739 # could update srcrepo.svfs and other variables to point to the new
772 # could update srcrepo.svfs and other variables to point to the new
740 # location. This is simpler.
773 # location. This is simpler.
741 backupvfs.unlink('store/lock')
774 backupvfs.unlink('store/lock')
742
775
743 return backuppath
776 return backuppath
744
777
745 def upgraderepo(ui, repo, run=False, optimize=None, backup=True):
778 def upgraderepo(ui, repo, run=False, optimize=None, backup=True):
746 """Upgrade a repository in place."""
779 """Upgrade a repository in place."""
747 if optimize is None:
780 if optimize is None:
748 optimize = []
781 optimize = []
749 optimize = set(legacy_opts_map.get(o, o) for o in optimize)
782 optimize = set(legacy_opts_map.get(o, o) for o in optimize)
750 repo = repo.unfiltered()
783 repo = repo.unfiltered()
751
784
752 # Ensure the repository can be upgraded.
785 # Ensure the repository can be upgraded.
753 missingreqs = requiredsourcerequirements(repo) - repo.requirements
786 missingreqs = requiredsourcerequirements(repo) - repo.requirements
754 if missingreqs:
787 if missingreqs:
755 raise error.Abort(_('cannot upgrade repository; requirement '
788 raise error.Abort(_('cannot upgrade repository; requirement '
756 'missing: %s') % _(', ').join(sorted(missingreqs)))
789 'missing: %s') % _(', ').join(sorted(missingreqs)))
757
790
758 blockedreqs = blocksourcerequirements(repo) & repo.requirements
791 blockedreqs = blocksourcerequirements(repo) & repo.requirements
759 if blockedreqs:
792 if blockedreqs:
760 raise error.Abort(_('cannot upgrade repository; unsupported source '
793 raise error.Abort(_('cannot upgrade repository; unsupported source '
761 'requirement: %s') %
794 'requirement: %s') %
762 _(', ').join(sorted(blockedreqs)))
795 _(', ').join(sorted(blockedreqs)))
763
796
764 # FUTURE there is potentially a need to control the wanted requirements via
797 # FUTURE there is potentially a need to control the wanted requirements via
765 # command arguments or via an extension hook point.
798 # command arguments or via an extension hook point.
766 newreqs = localrepo.newreporequirements(
799 newreqs = localrepo.newreporequirements(
767 repo.ui, localrepo.defaultcreateopts(repo.ui))
800 repo.ui, localrepo.defaultcreateopts(repo.ui))
768 newreqs.update(preservedrequirements(repo))
801 newreqs.update(preservedrequirements(repo))
769
802
770 noremovereqs = (repo.requirements - newreqs -
803 noremovereqs = (repo.requirements - newreqs -
771 supportremovedrequirements(repo))
804 supportremovedrequirements(repo))
772 if noremovereqs:
805 if noremovereqs:
773 raise error.Abort(_('cannot upgrade repository; requirement would be '
806 raise error.Abort(_('cannot upgrade repository; requirement would be '
774 'removed: %s') % _(', ').join(sorted(noremovereqs)))
807 'removed: %s') % _(', ').join(sorted(noremovereqs)))
775
808
776 noaddreqs = (newreqs - repo.requirements -
809 noaddreqs = (newreqs - repo.requirements -
777 allowednewrequirements(repo))
810 allowednewrequirements(repo))
778 if noaddreqs:
811 if noaddreqs:
779 raise error.Abort(_('cannot upgrade repository; do not support adding '
812 raise error.Abort(_('cannot upgrade repository; do not support adding '
780 'requirement: %s') %
813 'requirement: %s') %
781 _(', ').join(sorted(noaddreqs)))
814 _(', ').join(sorted(noaddreqs)))
782
815
783 unsupportedreqs = newreqs - supporteddestrequirements(repo)
816 unsupportedreqs = newreqs - supporteddestrequirements(repo)
784 if unsupportedreqs:
817 if unsupportedreqs:
785 raise error.Abort(_('cannot upgrade repository; do not support '
818 raise error.Abort(_('cannot upgrade repository; do not support '
786 'destination requirement: %s') %
819 'destination requirement: %s') %
787 _(', ').join(sorted(unsupportedreqs)))
820 _(', ').join(sorted(unsupportedreqs)))
788
821
789 # Find and validate all improvements that can be made.
822 # Find and validate all improvements that can be made.
790 alloptimizations = findoptimizations(repo)
823 alloptimizations = findoptimizations(repo)
791
824
792 # Apply and Validate arguments.
825 # Apply and Validate arguments.
793 optimizations = []
826 optimizations = []
794 for o in alloptimizations:
827 for o in alloptimizations:
795 if o.name in optimize:
828 if o.name in optimize:
796 optimizations.append(o)
829 optimizations.append(o)
797 optimize.discard(o.name)
830 optimize.discard(o.name)
798
831
799 if optimize: # anything left is unknown
832 if optimize: # anything left is unknown
800 raise error.Abort(_('unknown optimization action requested: %s') %
833 raise error.Abort(_('unknown optimization action requested: %s') %
801 ', '.join(sorted(optimize)),
834 ', '.join(sorted(optimize)),
802 hint=_('run without arguments to see valid '
835 hint=_('run without arguments to see valid '
803 'optimizations'))
836 'optimizations'))
804
837
805 deficiencies = finddeficiencies(repo)
838 deficiencies = finddeficiencies(repo)
806 actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
839 actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
807 actions.extend(o for o in sorted(optimizations)
840 actions.extend(o for o in sorted(optimizations)
808 # determineactions could have added optimisation
841 # determineactions could have added optimisation
809 if o not in actions)
842 if o not in actions)
810
843
811 def printrequirements():
844 def printrequirements():
812 ui.write(_('requirements\n'))
845 ui.write(_('requirements\n'))
813 ui.write(_(' preserved: %s\n') %
846 ui.write(_(' preserved: %s\n') %
814 _(', ').join(sorted(newreqs & repo.requirements)))
847 _(', ').join(sorted(newreqs & repo.requirements)))
815
848
816 if repo.requirements - newreqs:
849 if repo.requirements - newreqs:
817 ui.write(_(' removed: %s\n') %
850 ui.write(_(' removed: %s\n') %
818 _(', ').join(sorted(repo.requirements - newreqs)))
851 _(', ').join(sorted(repo.requirements - newreqs)))
819
852
820 if newreqs - repo.requirements:
853 if newreqs - repo.requirements:
821 ui.write(_(' added: %s\n') %
854 ui.write(_(' added: %s\n') %
822 _(', ').join(sorted(newreqs - repo.requirements)))
855 _(', ').join(sorted(newreqs - repo.requirements)))
823
856
824 ui.write('\n')
857 ui.write('\n')
825
858
826 def printupgradeactions():
859 def printupgradeactions():
827 for a in actions:
860 for a in actions:
828 ui.write('%s\n %s\n\n' % (a.name, a.upgrademessage))
861 ui.write('%s\n %s\n\n' % (a.name, a.upgrademessage))
829
862
830 if not run:
863 if not run:
831 fromconfig = []
864 fromconfig = []
832 onlydefault = []
865 onlydefault = []
833
866
834 for d in deficiencies:
867 for d in deficiencies:
835 if d.fromconfig(repo):
868 if d.fromconfig(repo):
836 fromconfig.append(d)
869 fromconfig.append(d)
837 elif d.default:
870 elif d.default:
838 onlydefault.append(d)
871 onlydefault.append(d)
839
872
840 if fromconfig or onlydefault:
873 if fromconfig or onlydefault:
841
874
842 if fromconfig:
875 if fromconfig:
843 ui.write(_('repository lacks features recommended by '
876 ui.write(_('repository lacks features recommended by '
844 'current config options:\n\n'))
877 'current config options:\n\n'))
845 for i in fromconfig:
878 for i in fromconfig:
846 ui.write('%s\n %s\n\n' % (i.name, i.description))
879 ui.write('%s\n %s\n\n' % (i.name, i.description))
847
880
848 if onlydefault:
881 if onlydefault:
849 ui.write(_('repository lacks features used by the default '
882 ui.write(_('repository lacks features used by the default '
850 'config options:\n\n'))
883 'config options:\n\n'))
851 for i in onlydefault:
884 for i in onlydefault:
852 ui.write('%s\n %s\n\n' % (i.name, i.description))
885 ui.write('%s\n %s\n\n' % (i.name, i.description))
853
886
854 ui.write('\n')
887 ui.write('\n')
855 else:
888 else:
856 ui.write(_('(no feature deficiencies found in existing '
889 ui.write(_('(no feature deficiencies found in existing '
857 'repository)\n'))
890 'repository)\n'))
858
891
859 ui.write(_('performing an upgrade with "--run" will make the following '
892 ui.write(_('performing an upgrade with "--run" will make the following '
860 'changes:\n\n'))
893 'changes:\n\n'))
861
894
862 printrequirements()
895 printrequirements()
863 printupgradeactions()
896 printupgradeactions()
864
897
865 unusedoptimize = [i for i in alloptimizations if i not in actions]
898 unusedoptimize = [i for i in alloptimizations if i not in actions]
866
899
867 if unusedoptimize:
900 if unusedoptimize:
868 ui.write(_('additional optimizations are available by specifying '
901 ui.write(_('additional optimizations are available by specifying '
869 '"--optimize <name>":\n\n'))
902 '"--optimize <name>":\n\n'))
870 for i in unusedoptimize:
903 for i in unusedoptimize:
871 ui.write(_('%s\n %s\n\n') % (i.name, i.description))
904 ui.write(_('%s\n %s\n\n') % (i.name, i.description))
872 return
905 return
873
906
874 # Else we're in the run=true case.
907 # Else we're in the run=true case.
875 ui.write(_('upgrade will perform the following actions:\n\n'))
908 ui.write(_('upgrade will perform the following actions:\n\n'))
876 printrequirements()
909 printrequirements()
877 printupgradeactions()
910 printupgradeactions()
878
911
879 upgradeactions = [a.name for a in actions]
912 upgradeactions = [a.name for a in actions]
880
913
881 ui.write(_('beginning upgrade...\n'))
914 ui.write(_('beginning upgrade...\n'))
882 with repo.wlock(), repo.lock():
915 with repo.wlock(), repo.lock():
883 ui.write(_('repository locked and read-only\n'))
916 ui.write(_('repository locked and read-only\n'))
884 # Our strategy for upgrading the repository is to create a new,
917 # Our strategy for upgrading the repository is to create a new,
885 # temporary repository, write data to it, then do a swap of the
918 # temporary repository, write data to it, then do a swap of the
886 # data. There are less heavyweight ways to do this, but it is easier
919 # data. There are less heavyweight ways to do this, but it is easier
887 # to create a new repo object than to instantiate all the components
920 # to create a new repo object than to instantiate all the components
888 # (like the store) separately.
921 # (like the store) separately.
889 tmppath = pycompat.mkdtemp(prefix='upgrade.', dir=repo.path)
922 tmppath = pycompat.mkdtemp(prefix='upgrade.', dir=repo.path)
890 backuppath = None
923 backuppath = None
891 try:
924 try:
892 ui.write(_('creating temporary repository to stage migrated '
925 ui.write(_('creating temporary repository to stage migrated '
893 'data: %s\n') % tmppath)
926 'data: %s\n') % tmppath)
894
927
895 # clone ui without using ui.copy because repo.ui is protected
928 # clone ui without using ui.copy because repo.ui is protected
896 repoui = repo.ui.__class__(repo.ui)
929 repoui = repo.ui.__class__(repo.ui)
897 dstrepo = hg.repository(repoui, path=tmppath, create=True)
930 dstrepo = hg.repository(repoui, path=tmppath, create=True)
898
931
899 with dstrepo.wlock(), dstrepo.lock():
932 with dstrepo.wlock(), dstrepo.lock():
900 backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
933 backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
901 upgradeactions)
934 upgradeactions)
902 if not (backup or backuppath is None):
935 if not (backup or backuppath is None):
903 ui.write(_('removing old repository content%s\n') % backuppath)
936 ui.write(_('removing old repository content%s\n') % backuppath)
904 repo.vfs.rmtree(backuppath, forcibly=True)
937 repo.vfs.rmtree(backuppath, forcibly=True)
905 backuppath = None
938 backuppath = None
906
939
907 finally:
940 finally:
908 ui.write(_('removing temporary repository %s\n') % tmppath)
941 ui.write(_('removing temporary repository %s\n') % tmppath)
909 repo.vfs.rmtree(tmppath, forcibly=True)
942 repo.vfs.rmtree(tmppath, forcibly=True)
910
943
911 if backuppath:
944 if backuppath:
912 ui.warn(_('copy of old repository backed up at %s\n') %
945 ui.warn(_('copy of old repository backed up at %s\n') %
913 backuppath)
946 backuppath)
914 ui.warn(_('the old repository will not be deleted; remove '
947 ui.warn(_('the old repository will not be deleted; remove '
915 'it to free up disk space once the upgraded '
948 'it to free up disk space once the upgraded '
916 'repository is verified\n'))
949 'repository is verified\n'))
@@ -1,843 +1,857 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > share =
5 > share =
6 > EOF
6 > EOF
7
7
8 store and revlogv1 are required in source
8 store and revlogv1 are required in source
9
9
10 $ hg --config format.usestore=false init no-store
10 $ hg --config format.usestore=false init no-store
11 $ hg -R no-store debugupgraderepo
11 $ hg -R no-store debugupgraderepo
12 abort: cannot upgrade repository; requirement missing: store
12 abort: cannot upgrade repository; requirement missing: store
13 [255]
13 [255]
14
14
15 $ hg init no-revlogv1
15 $ hg init no-revlogv1
16 $ cat > no-revlogv1/.hg/requires << EOF
16 $ cat > no-revlogv1/.hg/requires << EOF
17 > dotencode
17 > dotencode
18 > fncache
18 > fncache
19 > generaldelta
19 > generaldelta
20 > store
20 > store
21 > EOF
21 > EOF
22
22
23 $ hg -R no-revlogv1 debugupgraderepo
23 $ hg -R no-revlogv1 debugupgraderepo
24 abort: cannot upgrade repository; requirement missing: revlogv1
24 abort: cannot upgrade repository; requirement missing: revlogv1
25 [255]
25 [255]
26
26
27 Cannot upgrade shared repositories
27 Cannot upgrade shared repositories
28
28
29 $ hg init share-parent
29 $ hg init share-parent
30 $ hg -q share share-parent share-child
30 $ hg -q share share-parent share-child
31
31
32 $ hg -R share-child debugupgraderepo
32 $ hg -R share-child debugupgraderepo
33 abort: cannot upgrade repository; unsupported source requirement: shared
33 abort: cannot upgrade repository; unsupported source requirement: shared
34 [255]
34 [255]
35
35
36 Do not yet support upgrading treemanifest repos
36 Do not yet support upgrading treemanifest repos
37
37
38 $ hg --config experimental.treemanifest=true init treemanifest
38 $ hg --config experimental.treemanifest=true init treemanifest
39 $ hg -R treemanifest debugupgraderepo
39 $ hg -R treemanifest debugupgraderepo
40 abort: cannot upgrade repository; unsupported source requirement: treemanifest
40 abort: cannot upgrade repository; unsupported source requirement: treemanifest
41 [255]
41 [255]
42
42
43 Cannot add treemanifest requirement during upgrade
43 Cannot add treemanifest requirement during upgrade
44
44
45 $ hg init disallowaddedreq
45 $ hg init disallowaddedreq
46 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
46 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
47 abort: cannot upgrade repository; do not support adding requirement: treemanifest
47 abort: cannot upgrade repository; do not support adding requirement: treemanifest
48 [255]
48 [255]
49
49
50 An upgrade of a repository created with recommended settings only suggests optimizations
50 An upgrade of a repository created with recommended settings only suggests optimizations
51
51
52 $ hg init empty
52 $ hg init empty
53 $ cd empty
53 $ cd empty
54 $ hg debugformat
54 $ hg debugformat
55 format-variant repo
55 format-variant repo
56 fncache: yes
56 fncache: yes
57 dotencode: yes
57 dotencode: yes
58 generaldelta: yes
58 generaldelta: yes
59 sparserevlog: yes
59 sparserevlog: yes
60 plain-cl-delta: yes
60 plain-cl-delta: yes
61 compression: zlib
61 compression: zlib
62 compression-level: default
62 $ hg debugformat --verbose
63 $ hg debugformat --verbose
63 format-variant repo config default
64 format-variant repo config default
64 fncache: yes yes yes
65 fncache: yes yes yes
65 dotencode: yes yes yes
66 dotencode: yes yes yes
66 generaldelta: yes yes yes
67 generaldelta: yes yes yes
67 sparserevlog: yes yes yes
68 sparserevlog: yes yes yes
68 plain-cl-delta: yes yes yes
69 plain-cl-delta: yes yes yes
69 compression: zlib zlib zlib
70 compression: zlib zlib zlib
71 compression-level: default default default
70 $ hg debugformat --verbose --config format.usefncache=no
72 $ hg debugformat --verbose --config format.usefncache=no
71 format-variant repo config default
73 format-variant repo config default
72 fncache: yes no yes
74 fncache: yes no yes
73 dotencode: yes no yes
75 dotencode: yes no yes
74 generaldelta: yes yes yes
76 generaldelta: yes yes yes
75 sparserevlog: yes yes yes
77 sparserevlog: yes yes yes
76 plain-cl-delta: yes yes yes
78 plain-cl-delta: yes yes yes
77 compression: zlib zlib zlib
79 compression: zlib zlib zlib
80 compression-level: default default default
78 $ hg debugformat --verbose --config format.usefncache=no --color=debug
81 $ hg debugformat --verbose --config format.usefncache=no --color=debug
79 format-variant repo config default
82 format-variant repo config default
80 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
83 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
81 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
84 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
82 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
85 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
83 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
86 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
84 [formatvariant.name.uptodate|plain-cl-delta:][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
87 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
85 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
88 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
89 [formatvariant.name.uptodate|compression-level:][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
86 $ hg debugformat -Tjson
90 $ hg debugformat -Tjson
87 [
91 [
88 {
92 {
89 "config": true,
93 "config": true,
90 "default": true,
94 "default": true,
91 "name": "fncache",
95 "name": "fncache",
92 "repo": true
96 "repo": true
93 },
97 },
94 {
98 {
95 "config": true,
99 "config": true,
96 "default": true,
100 "default": true,
97 "name": "dotencode",
101 "name": "dotencode",
98 "repo": true
102 "repo": true
99 },
103 },
100 {
104 {
101 "config": true,
105 "config": true,
102 "default": true,
106 "default": true,
103 "name": "generaldelta",
107 "name": "generaldelta",
104 "repo": true
108 "repo": true
105 },
109 },
106 {
110 {
107 "config": true,
111 "config": true,
108 "default": true,
112 "default": true,
109 "name": "sparserevlog",
113 "name": "sparserevlog",
110 "repo": true
114 "repo": true
111 },
115 },
112 {
116 {
113 "config": true,
117 "config": true,
114 "default": true,
118 "default": true,
115 "name": "plain-cl-delta",
119 "name": "plain-cl-delta",
116 "repo": true
120 "repo": true
117 },
121 },
118 {
122 {
119 "config": "zlib",
123 "config": "zlib",
120 "default": "zlib",
124 "default": "zlib",
121 "name": "compression",
125 "name": "compression",
122 "repo": "zlib"
126 "repo": "zlib"
127 },
128 {
129 "config": "default",
130 "default": "default",
131 "name": "compression-level",
132 "repo": "default"
123 }
133 }
124 ]
134 ]
125 $ hg debugupgraderepo
135 $ hg debugupgraderepo
126 (no feature deficiencies found in existing repository)
136 (no feature deficiencies found in existing repository)
127 performing an upgrade with "--run" will make the following changes:
137 performing an upgrade with "--run" will make the following changes:
128
138
129 requirements
139 requirements
130 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
140 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
131
141
132 additional optimizations are available by specifying "--optimize <name>":
142 additional optimizations are available by specifying "--optimize <name>":
133
143
134 re-delta-parent
144 re-delta-parent
135 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
145 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
136
146
137 re-delta-multibase
147 re-delta-multibase
138 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
148 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
139
149
140 re-delta-all
150 re-delta-all
141 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
151 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
142
152
143 re-delta-fulladd
153 re-delta-fulladd
144 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.
154 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.
145
155
146
156
147 --optimize can be used to add optimizations
157 --optimize can be used to add optimizations
148
158
149 $ hg debugupgrade --optimize redeltaparent
159 $ hg debugupgrade --optimize redeltaparent
150 (no feature deficiencies found in existing repository)
160 (no feature deficiencies found in existing repository)
151 performing an upgrade with "--run" will make the following changes:
161 performing an upgrade with "--run" will make the following changes:
152
162
153 requirements
163 requirements
154 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
164 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
155
165
156 re-delta-parent
166 re-delta-parent
157 deltas within internal storage will choose a new base revision if needed
167 deltas within internal storage will choose a new base revision if needed
158
168
159 additional optimizations are available by specifying "--optimize <name>":
169 additional optimizations are available by specifying "--optimize <name>":
160
170
161 re-delta-multibase
171 re-delta-multibase
162 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
172 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
163
173
164 re-delta-all
174 re-delta-all
165 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
175 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
166
176
167 re-delta-fulladd
177 re-delta-fulladd
168 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.
178 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.
169
179
170
180
171 modern form of the option
181 modern form of the option
172
182
173 $ hg debugupgrade --optimize re-delta-parent
183 $ hg debugupgrade --optimize re-delta-parent
174 (no feature deficiencies found in existing repository)
184 (no feature deficiencies found in existing repository)
175 performing an upgrade with "--run" will make the following changes:
185 performing an upgrade with "--run" will make the following changes:
176
186
177 requirements
187 requirements
178 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
188 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
179
189
180 re-delta-parent
190 re-delta-parent
181 deltas within internal storage will choose a new base revision if needed
191 deltas within internal storage will choose a new base revision if needed
182
192
183 additional optimizations are available by specifying "--optimize <name>":
193 additional optimizations are available by specifying "--optimize <name>":
184
194
185 re-delta-multibase
195 re-delta-multibase
186 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
196 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
187
197
188 re-delta-all
198 re-delta-all
189 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
199 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
190
200
191 re-delta-fulladd
201 re-delta-fulladd
192 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.
202 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.
193
203
194
204
195 unknown optimization:
205 unknown optimization:
196
206
197 $ hg debugupgrade --optimize foobar
207 $ hg debugupgrade --optimize foobar
198 abort: unknown optimization action requested: foobar
208 abort: unknown optimization action requested: foobar
199 (run without arguments to see valid optimizations)
209 (run without arguments to see valid optimizations)
200 [255]
210 [255]
201
211
202 Various sub-optimal detections work
212 Various sub-optimal detections work
203
213
204 $ cat > .hg/requires << EOF
214 $ cat > .hg/requires << EOF
205 > revlogv1
215 > revlogv1
206 > store
216 > store
207 > EOF
217 > EOF
208
218
209 $ hg debugformat
219 $ hg debugformat
210 format-variant repo
220 format-variant repo
211 fncache: no
221 fncache: no
212 dotencode: no
222 dotencode: no
213 generaldelta: no
223 generaldelta: no
214 sparserevlog: no
224 sparserevlog: no
215 plain-cl-delta: yes
225 plain-cl-delta: yes
216 compression: zlib
226 compression: zlib
227 compression-level: default
217 $ hg debugformat --verbose
228 $ hg debugformat --verbose
218 format-variant repo config default
229 format-variant repo config default
219 fncache: no yes yes
230 fncache: no yes yes
220 dotencode: no yes yes
231 dotencode: no yes yes
221 generaldelta: no yes yes
232 generaldelta: no yes yes
222 sparserevlog: no yes yes
233 sparserevlog: no yes yes
223 plain-cl-delta: yes yes yes
234 plain-cl-delta: yes yes yes
224 compression: zlib zlib zlib
235 compression: zlib zlib zlib
236 compression-level: default default default
225 $ hg debugformat --verbose --config format.usegeneraldelta=no
237 $ hg debugformat --verbose --config format.usegeneraldelta=no
226 format-variant repo config default
238 format-variant repo config default
227 fncache: no yes yes
239 fncache: no yes yes
228 dotencode: no yes yes
240 dotencode: no yes yes
229 generaldelta: no no yes
241 generaldelta: no no yes
230 sparserevlog: no no yes
242 sparserevlog: no no yes
231 plain-cl-delta: yes yes yes
243 plain-cl-delta: yes yes yes
232 compression: zlib zlib zlib
244 compression: zlib zlib zlib
245 compression-level: default default default
233 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
246 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
234 format-variant repo config default
247 format-variant repo config default
235 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
248 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
236 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
249 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
237 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
250 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
238 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
251 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
239 [formatvariant.name.uptodate|plain-cl-delta:][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
252 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
240 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
253 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
254 [formatvariant.name.uptodate|compression-level:][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
241 $ hg debugupgraderepo
255 $ hg debugupgraderepo
242 repository lacks features recommended by current config options:
256 repository lacks features recommended by current config options:
243
257
244 fncache
258 fncache
245 long and reserved filenames may not work correctly; repository performance is sub-optimal
259 long and reserved filenames may not work correctly; repository performance is sub-optimal
246
260
247 dotencode
261 dotencode
248 storage of filenames beginning with a period or space may not work correctly
262 storage of filenames beginning with a period or space may not work correctly
249
263
250 generaldelta
264 generaldelta
251 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
265 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
252
266
253 sparserevlog
267 sparserevlog
254 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.
268 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.
255
269
256
270
257 performing an upgrade with "--run" will make the following changes:
271 performing an upgrade with "--run" will make the following changes:
258
272
259 requirements
273 requirements
260 preserved: revlogv1, store
274 preserved: revlogv1, store
261 added: dotencode, fncache, generaldelta, sparserevlog
275 added: dotencode, fncache, generaldelta, sparserevlog
262
276
263 fncache
277 fncache
264 repository will be more resilient to storing certain paths and performance of certain operations should be improved
278 repository will be more resilient to storing certain paths and performance of certain operations should be improved
265
279
266 dotencode
280 dotencode
267 repository will be better able to store files beginning with a space or period
281 repository will be better able to store files beginning with a space or period
268
282
269 generaldelta
283 generaldelta
270 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
284 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
271
285
272 sparserevlog
286 sparserevlog
273 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.
287 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.
274
288
275 additional optimizations are available by specifying "--optimize <name>":
289 additional optimizations are available by specifying "--optimize <name>":
276
290
277 re-delta-parent
291 re-delta-parent
278 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
292 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
279
293
280 re-delta-multibase
294 re-delta-multibase
281 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
295 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
282
296
283 re-delta-all
297 re-delta-all
284 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
298 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
285
299
286 re-delta-fulladd
300 re-delta-fulladd
287 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.
301 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.
288
302
289
303
290 $ hg --config format.dotencode=false debugupgraderepo
304 $ hg --config format.dotencode=false debugupgraderepo
291 repository lacks features recommended by current config options:
305 repository lacks features recommended by current config options:
292
306
293 fncache
307 fncache
294 long and reserved filenames may not work correctly; repository performance is sub-optimal
308 long and reserved filenames may not work correctly; repository performance is sub-optimal
295
309
296 generaldelta
310 generaldelta
297 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
311 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
298
312
299 sparserevlog
313 sparserevlog
300 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.
314 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.
301
315
302 repository lacks features used by the default config options:
316 repository lacks features used by the default config options:
303
317
304 dotencode
318 dotencode
305 storage of filenames beginning with a period or space may not work correctly
319 storage of filenames beginning with a period or space may not work correctly
306
320
307
321
308 performing an upgrade with "--run" will make the following changes:
322 performing an upgrade with "--run" will make the following changes:
309
323
310 requirements
324 requirements
311 preserved: revlogv1, store
325 preserved: revlogv1, store
312 added: fncache, generaldelta, sparserevlog
326 added: fncache, generaldelta, sparserevlog
313
327
314 fncache
328 fncache
315 repository will be more resilient to storing certain paths and performance of certain operations should be improved
329 repository will be more resilient to storing certain paths and performance of certain operations should be improved
316
330
317 generaldelta
331 generaldelta
318 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
332 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
319
333
320 sparserevlog
334 sparserevlog
321 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.
335 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.
322
336
323 additional optimizations are available by specifying "--optimize <name>":
337 additional optimizations are available by specifying "--optimize <name>":
324
338
325 re-delta-parent
339 re-delta-parent
326 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
340 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
327
341
328 re-delta-multibase
342 re-delta-multibase
329 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
343 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
330
344
331 re-delta-all
345 re-delta-all
332 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
346 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
333
347
334 re-delta-fulladd
348 re-delta-fulladd
335 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.
349 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.
336
350
337
351
338 $ cd ..
352 $ cd ..
339
353
340 Upgrading a repository that is already modern essentially no-ops
354 Upgrading a repository that is already modern essentially no-ops
341
355
342 $ hg init modern
356 $ hg init modern
343 $ hg -R modern debugupgraderepo --run
357 $ hg -R modern debugupgraderepo --run
344 upgrade will perform the following actions:
358 upgrade will perform the following actions:
345
359
346 requirements
360 requirements
347 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
361 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
348
362
349 beginning upgrade...
363 beginning upgrade...
350 repository locked and read-only
364 repository locked and read-only
351 creating temporary repository to stage migrated data: $TESTTMP/modern/.hg/upgrade.* (glob)
365 creating temporary repository to stage migrated data: $TESTTMP/modern/.hg/upgrade.* (glob)
352 (it is safe to interrupt this process any time before data migration completes)
366 (it is safe to interrupt this process any time before data migration completes)
353 data fully migrated to temporary repository
367 data fully migrated to temporary repository
354 marking source repository as being upgraded; clients will be unable to read from repository
368 marking source repository as being upgraded; clients will be unable to read from repository
355 starting in-place swap of repository data
369 starting in-place swap of repository data
356 replaced files will be backed up at $TESTTMP/modern/.hg/upgradebackup.* (glob)
370 replaced files will be backed up at $TESTTMP/modern/.hg/upgradebackup.* (glob)
357 replacing store...
371 replacing store...
358 store replacement complete; repository was inconsistent for *s (glob)
372 store replacement complete; repository was inconsistent for *s (glob)
359 finalizing requirements file and making repository readable again
373 finalizing requirements file and making repository readable again
360 removing temporary repository $TESTTMP/modern/.hg/upgrade.* (glob)
374 removing temporary repository $TESTTMP/modern/.hg/upgrade.* (glob)
361 copy of old repository backed up at $TESTTMP/modern/.hg/upgradebackup.* (glob)
375 copy of old repository backed up at $TESTTMP/modern/.hg/upgradebackup.* (glob)
362 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
376 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
363
377
364 Upgrading a repository to generaldelta works
378 Upgrading a repository to generaldelta works
365
379
366 $ hg --config format.usegeneraldelta=false init upgradegd
380 $ hg --config format.usegeneraldelta=false init upgradegd
367 $ cd upgradegd
381 $ cd upgradegd
368 $ touch f0
382 $ touch f0
369 $ hg -q commit -A -m initial
383 $ hg -q commit -A -m initial
370 $ touch f1
384 $ touch f1
371 $ hg -q commit -A -m 'add f1'
385 $ hg -q commit -A -m 'add f1'
372 $ hg -q up -r 0
386 $ hg -q up -r 0
373 $ touch f2
387 $ touch f2
374 $ hg -q commit -A -m 'add f2'
388 $ hg -q commit -A -m 'add f2'
375
389
376 $ hg debugupgraderepo --run --config format.sparse-revlog=false
390 $ hg debugupgraderepo --run --config format.sparse-revlog=false
377 upgrade will perform the following actions:
391 upgrade will perform the following actions:
378
392
379 requirements
393 requirements
380 preserved: dotencode, fncache, revlogv1, store
394 preserved: dotencode, fncache, revlogv1, store
381 added: generaldelta
395 added: generaldelta
382
396
383 generaldelta
397 generaldelta
384 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
398 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
385
399
386 beginning upgrade...
400 beginning upgrade...
387 repository locked and read-only
401 repository locked and read-only
388 creating temporary repository to stage migrated data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
402 creating temporary repository to stage migrated data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
389 (it is safe to interrupt this process any time before data migration completes)
403 (it is safe to interrupt this process any time before data migration completes)
390 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
404 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
391 migrating 917 bytes in store; 401 bytes tracked data
405 migrating 917 bytes in store; 401 bytes tracked data
392 migrating 3 filelogs containing 3 revisions (192 bytes in store; 0 bytes tracked data)
406 migrating 3 filelogs containing 3 revisions (192 bytes in store; 0 bytes tracked data)
393 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
407 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
394 migrating 1 manifests containing 3 revisions (349 bytes in store; 220 bytes tracked data)
408 migrating 1 manifests containing 3 revisions (349 bytes in store; 220 bytes tracked data)
395 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
409 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
396 migrating changelog containing 3 revisions (376 bytes in store; 181 bytes tracked data)
410 migrating changelog containing 3 revisions (376 bytes in store; 181 bytes tracked data)
397 finished migrating 3 changelog revisions; change in size: 0 bytes
411 finished migrating 3 changelog revisions; change in size: 0 bytes
398 finished migrating 9 total revisions; total change in store size: 0 bytes
412 finished migrating 9 total revisions; total change in store size: 0 bytes
399 copying phaseroots
413 copying phaseroots
400 data fully migrated to temporary repository
414 data fully migrated to temporary repository
401 marking source repository as being upgraded; clients will be unable to read from repository
415 marking source repository as being upgraded; clients will be unable to read from repository
402 starting in-place swap of repository data
416 starting in-place swap of repository data
403 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
417 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
404 replacing store...
418 replacing store...
405 store replacement complete; repository was inconsistent for *s (glob)
419 store replacement complete; repository was inconsistent for *s (glob)
406 finalizing requirements file and making repository readable again
420 finalizing requirements file and making repository readable again
407 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
421 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
408 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
422 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
409 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
423 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
410
424
411 Original requirements backed up
425 Original requirements backed up
412
426
413 $ cat .hg/upgradebackup.*/requires
427 $ cat .hg/upgradebackup.*/requires
414 dotencode
428 dotencode
415 fncache
429 fncache
416 revlogv1
430 revlogv1
417 store
431 store
418
432
419 generaldelta added to original requirements files
433 generaldelta added to original requirements files
420
434
421 $ cat .hg/requires
435 $ cat .hg/requires
422 dotencode
436 dotencode
423 fncache
437 fncache
424 generaldelta
438 generaldelta
425 revlogv1
439 revlogv1
426 store
440 store
427
441
428 store directory has files we expect
442 store directory has files we expect
429
443
430 $ ls .hg/store
444 $ ls .hg/store
431 00changelog.i
445 00changelog.i
432 00manifest.i
446 00manifest.i
433 data
447 data
434 fncache
448 fncache
435 phaseroots
449 phaseroots
436 undo
450 undo
437 undo.backupfiles
451 undo.backupfiles
438 undo.phaseroots
452 undo.phaseroots
439
453
440 manifest should be generaldelta
454 manifest should be generaldelta
441
455
442 $ hg debugrevlog -m | grep flags
456 $ hg debugrevlog -m | grep flags
443 flags : inline, generaldelta
457 flags : inline, generaldelta
444
458
445 verify should be happy
459 verify should be happy
446
460
447 $ hg verify
461 $ hg verify
448 checking changesets
462 checking changesets
449 checking manifests
463 checking manifests
450 crosschecking files in changesets and manifests
464 crosschecking files in changesets and manifests
451 checking files
465 checking files
452 checked 3 changesets with 3 changes to 3 files
466 checked 3 changesets with 3 changes to 3 files
453
467
454 old store should be backed up
468 old store should be backed up
455
469
456 $ ls -d .hg/upgradebackup.*/
470 $ ls -d .hg/upgradebackup.*/
457 .hg/upgradebackup.*/ (glob)
471 .hg/upgradebackup.*/ (glob)
458 $ ls .hg/upgradebackup.*/store
472 $ ls .hg/upgradebackup.*/store
459 00changelog.i
473 00changelog.i
460 00manifest.i
474 00manifest.i
461 data
475 data
462 fncache
476 fncache
463 phaseroots
477 phaseroots
464 undo
478 undo
465 undo.backup.fncache
479 undo.backup.fncache
466 undo.backupfiles
480 undo.backupfiles
467 undo.phaseroots
481 undo.phaseroots
468
482
469 unless --no-backup is passed
483 unless --no-backup is passed
470
484
471 $ rm -rf .hg/upgradebackup.*/
485 $ rm -rf .hg/upgradebackup.*/
472 $ hg debugupgraderepo --run --no-backup
486 $ hg debugupgraderepo --run --no-backup
473 upgrade will perform the following actions:
487 upgrade will perform the following actions:
474
488
475 requirements
489 requirements
476 preserved: dotencode, fncache, generaldelta, revlogv1, store
490 preserved: dotencode, fncache, generaldelta, revlogv1, store
477 added: sparserevlog
491 added: sparserevlog
478
492
479 sparserevlog
493 sparserevlog
480 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.
494 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.
481
495
482 beginning upgrade...
496 beginning upgrade...
483 repository locked and read-only
497 repository locked and read-only
484 creating temporary repository to stage migrated data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
498 creating temporary repository to stage migrated data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
485 (it is safe to interrupt this process any time before data migration completes)
499 (it is safe to interrupt this process any time before data migration completes)
486 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
500 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
487 migrating 917 bytes in store; 401 bytes tracked data
501 migrating 917 bytes in store; 401 bytes tracked data
488 migrating 3 filelogs containing 3 revisions (192 bytes in store; 0 bytes tracked data)
502 migrating 3 filelogs containing 3 revisions (192 bytes in store; 0 bytes tracked data)
489 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
503 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
490 migrating 1 manifests containing 3 revisions (349 bytes in store; 220 bytes tracked data)
504 migrating 1 manifests containing 3 revisions (349 bytes in store; 220 bytes tracked data)
491 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
505 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
492 migrating changelog containing 3 revisions (376 bytes in store; 181 bytes tracked data)
506 migrating changelog containing 3 revisions (376 bytes in store; 181 bytes tracked data)
493 finished migrating 3 changelog revisions; change in size: 0 bytes
507 finished migrating 3 changelog revisions; change in size: 0 bytes
494 finished migrating 9 total revisions; total change in store size: 0 bytes
508 finished migrating 9 total revisions; total change in store size: 0 bytes
495 copying phaseroots
509 copying phaseroots
496 data fully migrated to temporary repository
510 data fully migrated to temporary repository
497 marking source repository as being upgraded; clients will be unable to read from repository
511 marking source repository as being upgraded; clients will be unable to read from repository
498 starting in-place swap of repository data
512 starting in-place swap of repository data
499 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
513 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
500 replacing store...
514 replacing store...
501 store replacement complete; repository was inconsistent for * (glob)
515 store replacement complete; repository was inconsistent for * (glob)
502 finalizing requirements file and making repository readable again
516 finalizing requirements file and making repository readable again
503 removing old repository content$TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
517 removing old repository content$TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
504 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
518 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
505 $ ls -1 .hg/ | grep upgradebackup
519 $ ls -1 .hg/ | grep upgradebackup
506 [1]
520 [1]
507 $ cd ..
521 $ cd ..
508
522
509
523
510 store files with special filenames aren't encoded during copy
524 store files with special filenames aren't encoded during copy
511
525
512 $ hg init store-filenames
526 $ hg init store-filenames
513 $ cd store-filenames
527 $ cd store-filenames
514 $ touch foo
528 $ touch foo
515 $ hg -q commit -A -m initial
529 $ hg -q commit -A -m initial
516 $ touch .hg/store/.XX_special_filename
530 $ touch .hg/store/.XX_special_filename
517
531
518 $ hg debugupgraderepo --run
532 $ hg debugupgraderepo --run
519 upgrade will perform the following actions:
533 upgrade will perform the following actions:
520
534
521 requirements
535 requirements
522 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
536 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
523
537
524 beginning upgrade...
538 beginning upgrade...
525 repository locked and read-only
539 repository locked and read-only
526 creating temporary repository to stage migrated data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
540 creating temporary repository to stage migrated data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
527 (it is safe to interrupt this process any time before data migration completes)
541 (it is safe to interrupt this process any time before data migration completes)
528 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
542 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
529 migrating 301 bytes in store; 107 bytes tracked data
543 migrating 301 bytes in store; 107 bytes tracked data
530 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
544 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
531 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
545 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
532 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
546 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
533 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
547 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
534 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
548 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
535 finished migrating 1 changelog revisions; change in size: 0 bytes
549 finished migrating 1 changelog revisions; change in size: 0 bytes
536 finished migrating 3 total revisions; total change in store size: 0 bytes
550 finished migrating 3 total revisions; total change in store size: 0 bytes
537 copying .XX_special_filename
551 copying .XX_special_filename
538 copying phaseroots
552 copying phaseroots
539 data fully migrated to temporary repository
553 data fully migrated to temporary repository
540 marking source repository as being upgraded; clients will be unable to read from repository
554 marking source repository as being upgraded; clients will be unable to read from repository
541 starting in-place swap of repository data
555 starting in-place swap of repository data
542 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
556 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
543 replacing store...
557 replacing store...
544 store replacement complete; repository was inconsistent for *s (glob)
558 store replacement complete; repository was inconsistent for *s (glob)
545 finalizing requirements file and making repository readable again
559 finalizing requirements file and making repository readable again
546 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
560 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
547 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
561 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
548 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
562 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
549 $ hg debugupgraderepo --run --optimize redeltafulladd
563 $ hg debugupgraderepo --run --optimize redeltafulladd
550 upgrade will perform the following actions:
564 upgrade will perform the following actions:
551
565
552 requirements
566 requirements
553 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
567 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
554
568
555 re-delta-fulladd
569 re-delta-fulladd
556 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
570 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
557
571
558 beginning upgrade...
572 beginning upgrade...
559 repository locked and read-only
573 repository locked and read-only
560 creating temporary repository to stage migrated data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
574 creating temporary repository to stage migrated data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
561 (it is safe to interrupt this process any time before data migration completes)
575 (it is safe to interrupt this process any time before data migration completes)
562 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
576 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
563 migrating 301 bytes in store; 107 bytes tracked data
577 migrating 301 bytes in store; 107 bytes tracked data
564 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
578 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
565 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
579 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
566 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
580 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
567 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
581 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
568 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
582 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
569 finished migrating 1 changelog revisions; change in size: 0 bytes
583 finished migrating 1 changelog revisions; change in size: 0 bytes
570 finished migrating 3 total revisions; total change in store size: 0 bytes
584 finished migrating 3 total revisions; total change in store size: 0 bytes
571 copying .XX_special_filename
585 copying .XX_special_filename
572 copying phaseroots
586 copying phaseroots
573 data fully migrated to temporary repository
587 data fully migrated to temporary repository
574 marking source repository as being upgraded; clients will be unable to read from repository
588 marking source repository as being upgraded; clients will be unable to read from repository
575 starting in-place swap of repository data
589 starting in-place swap of repository data
576 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
590 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
577 replacing store...
591 replacing store...
578 store replacement complete; repository was inconsistent for *s (glob)
592 store replacement complete; repository was inconsistent for *s (glob)
579 finalizing requirements file and making repository readable again
593 finalizing requirements file and making repository readable again
580 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
594 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
581 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
595 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
582 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
596 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
583
597
584 fncache is valid after upgrade
598 fncache is valid after upgrade
585
599
586 $ hg debugrebuildfncache
600 $ hg debugrebuildfncache
587 fncache already up to date
601 fncache already up to date
588
602
589 $ cd ..
603 $ cd ..
590
604
591 Check upgrading a large file repository
605 Check upgrading a large file repository
592 ---------------------------------------
606 ---------------------------------------
593
607
594 $ hg init largefilesrepo
608 $ hg init largefilesrepo
595 $ cat << EOF >> largefilesrepo/.hg/hgrc
609 $ cat << EOF >> largefilesrepo/.hg/hgrc
596 > [extensions]
610 > [extensions]
597 > largefiles =
611 > largefiles =
598 > EOF
612 > EOF
599
613
600 $ cd largefilesrepo
614 $ cd largefilesrepo
601 $ touch foo
615 $ touch foo
602 $ hg add --large foo
616 $ hg add --large foo
603 $ hg -q commit -m initial
617 $ hg -q commit -m initial
604 $ cat .hg/requires
618 $ cat .hg/requires
605 dotencode
619 dotencode
606 fncache
620 fncache
607 generaldelta
621 generaldelta
608 largefiles
622 largefiles
609 revlogv1
623 revlogv1
610 sparserevlog
624 sparserevlog
611 store
625 store
612
626
613 $ hg debugupgraderepo --run
627 $ hg debugupgraderepo --run
614 upgrade will perform the following actions:
628 upgrade will perform the following actions:
615
629
616 requirements
630 requirements
617 preserved: dotencode, fncache, generaldelta, largefiles, revlogv1, sparserevlog, store
631 preserved: dotencode, fncache, generaldelta, largefiles, revlogv1, sparserevlog, store
618
632
619 beginning upgrade...
633 beginning upgrade...
620 repository locked and read-only
634 repository locked and read-only
621 creating temporary repository to stage migrated data: $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
635 creating temporary repository to stage migrated data: $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
622 (it is safe to interrupt this process any time before data migration completes)
636 (it is safe to interrupt this process any time before data migration completes)
623 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
637 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
624 migrating 355 bytes in store; 160 bytes tracked data
638 migrating 355 bytes in store; 160 bytes tracked data
625 migrating 1 filelogs containing 1 revisions (106 bytes in store; 41 bytes tracked data)
639 migrating 1 filelogs containing 1 revisions (106 bytes in store; 41 bytes tracked data)
626 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
640 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
627 migrating 1 manifests containing 1 revisions (116 bytes in store; 51 bytes tracked data)
641 migrating 1 manifests containing 1 revisions (116 bytes in store; 51 bytes tracked data)
628 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
642 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
629 migrating changelog containing 1 revisions (133 bytes in store; 68 bytes tracked data)
643 migrating changelog containing 1 revisions (133 bytes in store; 68 bytes tracked data)
630 finished migrating 1 changelog revisions; change in size: 0 bytes
644 finished migrating 1 changelog revisions; change in size: 0 bytes
631 finished migrating 3 total revisions; total change in store size: 0 bytes
645 finished migrating 3 total revisions; total change in store size: 0 bytes
632 copying phaseroots
646 copying phaseroots
633 data fully migrated to temporary repository
647 data fully migrated to temporary repository
634 marking source repository as being upgraded; clients will be unable to read from repository
648 marking source repository as being upgraded; clients will be unable to read from repository
635 starting in-place swap of repository data
649 starting in-place swap of repository data
636 replaced files will be backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
650 replaced files will be backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
637 replacing store...
651 replacing store...
638 store replacement complete; repository was inconsistent for *s (glob)
652 store replacement complete; repository was inconsistent for *s (glob)
639 finalizing requirements file and making repository readable again
653 finalizing requirements file and making repository readable again
640 removing temporary repository $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
654 removing temporary repository $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
641 copy of old repository backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
655 copy of old repository backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
642 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
656 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
643 $ cat .hg/requires
657 $ cat .hg/requires
644 dotencode
658 dotencode
645 fncache
659 fncache
646 generaldelta
660 generaldelta
647 largefiles
661 largefiles
648 revlogv1
662 revlogv1
649 sparserevlog
663 sparserevlog
650 store
664 store
651
665
652 $ cat << EOF >> .hg/hgrc
666 $ cat << EOF >> .hg/hgrc
653 > [extensions]
667 > [extensions]
654 > lfs =
668 > lfs =
655 > [lfs]
669 > [lfs]
656 > threshold = 10
670 > threshold = 10
657 > EOF
671 > EOF
658 $ echo '123456789012345' > lfs.bin
672 $ echo '123456789012345' > lfs.bin
659 $ hg ci -Am 'lfs.bin'
673 $ hg ci -Am 'lfs.bin'
660 adding lfs.bin
674 adding lfs.bin
661 $ grep lfs .hg/requires
675 $ grep lfs .hg/requires
662 lfs
676 lfs
663 $ find .hg/store/lfs -type f
677 $ find .hg/store/lfs -type f
664 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
678 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
665
679
666 $ hg debugupgraderepo --run
680 $ hg debugupgraderepo --run
667 upgrade will perform the following actions:
681 upgrade will perform the following actions:
668
682
669 requirements
683 requirements
670 preserved: dotencode, fncache, generaldelta, largefiles, lfs, revlogv1, sparserevlog, store
684 preserved: dotencode, fncache, generaldelta, largefiles, lfs, revlogv1, sparserevlog, store
671
685
672 beginning upgrade...
686 beginning upgrade...
673 repository locked and read-only
687 repository locked and read-only
674 creating temporary repository to stage migrated data: $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
688 creating temporary repository to stage migrated data: $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
675 (it is safe to interrupt this process any time before data migration completes)
689 (it is safe to interrupt this process any time before data migration completes)
676 migrating 6 total revisions (2 in filelogs, 2 in manifests, 2 in changelog)
690 migrating 6 total revisions (2 in filelogs, 2 in manifests, 2 in changelog)
677 migrating 801 bytes in store; 467 bytes tracked data
691 migrating 801 bytes in store; 467 bytes tracked data
678 migrating 2 filelogs containing 2 revisions (296 bytes in store; 182 bytes tracked data)
692 migrating 2 filelogs containing 2 revisions (296 bytes in store; 182 bytes tracked data)
679 finished migrating 2 filelog revisions across 2 filelogs; change in size: 0 bytes
693 finished migrating 2 filelog revisions across 2 filelogs; change in size: 0 bytes
680 migrating 1 manifests containing 2 revisions (241 bytes in store; 151 bytes tracked data)
694 migrating 1 manifests containing 2 revisions (241 bytes in store; 151 bytes tracked data)
681 finished migrating 2 manifest revisions across 1 manifests; change in size: 0 bytes
695 finished migrating 2 manifest revisions across 1 manifests; change in size: 0 bytes
682 migrating changelog containing 2 revisions (264 bytes in store; 134 bytes tracked data)
696 migrating changelog containing 2 revisions (264 bytes in store; 134 bytes tracked data)
683 finished migrating 2 changelog revisions; change in size: 0 bytes
697 finished migrating 2 changelog revisions; change in size: 0 bytes
684 finished migrating 6 total revisions; total change in store size: 0 bytes
698 finished migrating 6 total revisions; total change in store size: 0 bytes
685 copying phaseroots
699 copying phaseroots
686 copying lfs blob d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
700 copying lfs blob d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
687 data fully migrated to temporary repository
701 data fully migrated to temporary repository
688 marking source repository as being upgraded; clients will be unable to read from repository
702 marking source repository as being upgraded; clients will be unable to read from repository
689 starting in-place swap of repository data
703 starting in-place swap of repository data
690 replaced files will be backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
704 replaced files will be backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
691 replacing store...
705 replacing store...
692 store replacement complete; repository was inconsistent for *s (glob)
706 store replacement complete; repository was inconsistent for *s (glob)
693 finalizing requirements file and making repository readable again
707 finalizing requirements file and making repository readable again
694 removing temporary repository $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
708 removing temporary repository $TESTTMP/largefilesrepo/.hg/upgrade.* (glob)
695 copy of old repository backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
709 copy of old repository backed up at $TESTTMP/largefilesrepo/.hg/upgradebackup.* (glob)
696 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
710 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
697
711
698 $ grep lfs .hg/requires
712 $ grep lfs .hg/requires
699 lfs
713 lfs
700 $ find .hg/store/lfs -type f
714 $ find .hg/store/lfs -type f
701 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
715 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
702 $ hg verify
716 $ hg verify
703 checking changesets
717 checking changesets
704 checking manifests
718 checking manifests
705 crosschecking files in changesets and manifests
719 crosschecking files in changesets and manifests
706 checking files
720 checking files
707 checked 2 changesets with 2 changes to 2 files
721 checked 2 changesets with 2 changes to 2 files
708 $ hg debugdata lfs.bin 0
722 $ hg debugdata lfs.bin 0
709 version https://git-lfs.github.com/spec/v1
723 version https://git-lfs.github.com/spec/v1
710 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
724 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
711 size 16
725 size 16
712 x-is-binary 0
726 x-is-binary 0
713
727
714 $ cd ..
728 $ cd ..
715
729
716 repository config is taken in account
730 repository config is taken in account
717 -------------------------------------
731 -------------------------------------
718
732
719 $ cat << EOF >> $HGRCPATH
733 $ cat << EOF >> $HGRCPATH
720 > [format]
734 > [format]
721 > maxchainlen = 1
735 > maxchainlen = 1
722 > EOF
736 > EOF
723
737
724 $ hg init localconfig
738 $ hg init localconfig
725 $ cd localconfig
739 $ cd localconfig
726 $ cat << EOF > file
740 $ cat << EOF > file
727 > some content
741 > some content
728 > with some length
742 > with some length
729 > to make sure we get a delta
743 > to make sure we get a delta
730 > after changes
744 > after changes
731 > very long
745 > very long
732 > very long
746 > very long
733 > very long
747 > very long
734 > very long
748 > very long
735 > very long
749 > very long
736 > very long
750 > very long
737 > very long
751 > very long
738 > very long
752 > very long
739 > very long
753 > very long
740 > very long
754 > very long
741 > very long
755 > very long
742 > EOF
756 > EOF
743 $ hg -q commit -A -m A
757 $ hg -q commit -A -m A
744 $ echo "new line" >> file
758 $ echo "new line" >> file
745 $ hg -q commit -m B
759 $ hg -q commit -m B
746 $ echo "new line" >> file
760 $ echo "new line" >> file
747 $ hg -q commit -m C
761 $ hg -q commit -m C
748
762
749 $ cat << EOF >> .hg/hgrc
763 $ cat << EOF >> .hg/hgrc
750 > [format]
764 > [format]
751 > maxchainlen = 9001
765 > maxchainlen = 9001
752 > EOF
766 > EOF
753 $ hg config format
767 $ hg config format
754 format.maxchainlen=9001
768 format.maxchainlen=9001
755 $ hg debugdeltachain file
769 $ hg debugdeltachain file
756 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
770 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
757 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
771 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
758 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
772 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
759 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
773 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
760
774
761 $ hg debugupgraderepo --run --optimize redeltaall
775 $ hg debugupgraderepo --run --optimize redeltaall
762 upgrade will perform the following actions:
776 upgrade will perform the following actions:
763
777
764 requirements
778 requirements
765 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
779 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
766
780
767 re-delta-all
781 re-delta-all
768 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
782 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
769
783
770 beginning upgrade...
784 beginning upgrade...
771 repository locked and read-only
785 repository locked and read-only
772 creating temporary repository to stage migrated data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
786 creating temporary repository to stage migrated data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
773 (it is safe to interrupt this process any time before data migration completes)
787 (it is safe to interrupt this process any time before data migration completes)
774 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
788 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
775 migrating 1019 bytes in store; 882 bytes tracked data
789 migrating 1019 bytes in store; 882 bytes tracked data
776 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
790 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
777 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
791 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
778 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
792 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
779 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
793 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
780 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
794 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
781 finished migrating 3 changelog revisions; change in size: 0 bytes
795 finished migrating 3 changelog revisions; change in size: 0 bytes
782 finished migrating 9 total revisions; total change in store size: -9 bytes
796 finished migrating 9 total revisions; total change in store size: -9 bytes
783 copying phaseroots
797 copying phaseroots
784 data fully migrated to temporary repository
798 data fully migrated to temporary repository
785 marking source repository as being upgraded; clients will be unable to read from repository
799 marking source repository as being upgraded; clients will be unable to read from repository
786 starting in-place swap of repository data
800 starting in-place swap of repository data
787 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
801 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
788 replacing store...
802 replacing store...
789 store replacement complete; repository was inconsistent for *s (glob)
803 store replacement complete; repository was inconsistent for *s (glob)
790 finalizing requirements file and making repository readable again
804 finalizing requirements file and making repository readable again
791 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
805 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
792 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
806 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
793 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
807 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
794 $ hg debugdeltachain file
808 $ hg debugdeltachain file
795 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
809 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
796 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
810 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
797 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
811 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
798 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
812 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
799 $ cd ..
813 $ cd ..
800
814
801 $ cat << EOF >> $HGRCPATH
815 $ cat << EOF >> $HGRCPATH
802 > [format]
816 > [format]
803 > maxchainlen = 9001
817 > maxchainlen = 9001
804 > EOF
818 > EOF
805
819
806 Check upgrading a sparse-revlog repository
820 Check upgrading a sparse-revlog repository
807 ---------------------------------------
821 ---------------------------------------
808
822
809 $ hg init sparserevlogrepo --config format.sparse-revlog=no
823 $ hg init sparserevlogrepo --config format.sparse-revlog=no
810 $ cd sparserevlogrepo
824 $ cd sparserevlogrepo
811 $ touch foo
825 $ touch foo
812 $ hg add foo
826 $ hg add foo
813 $ hg -q commit -m "foo"
827 $ hg -q commit -m "foo"
814 $ cat .hg/requires
828 $ cat .hg/requires
815 dotencode
829 dotencode
816 fncache
830 fncache
817 generaldelta
831 generaldelta
818 revlogv1
832 revlogv1
819 store
833 store
820
834
821 Check that we can add the sparse-revlog format requirement
835 Check that we can add the sparse-revlog format requirement
822 $ hg --config format.sparse-revlog=yes debugupgraderepo --run >/dev/null
836 $ hg --config format.sparse-revlog=yes debugupgraderepo --run >/dev/null
823 copy of old repository backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
837 copy of old repository backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
824 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
838 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
825 $ cat .hg/requires
839 $ cat .hg/requires
826 dotencode
840 dotencode
827 fncache
841 fncache
828 generaldelta
842 generaldelta
829 revlogv1
843 revlogv1
830 sparserevlog
844 sparserevlog
831 store
845 store
832
846
833 Check that we can remove the sparse-revlog format requirement
847 Check that we can remove the sparse-revlog format requirement
834 $ hg --config format.sparse-revlog=no debugupgraderepo --run >/dev/null
848 $ hg --config format.sparse-revlog=no debugupgraderepo --run >/dev/null
835 copy of old repository backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
849 copy of old repository backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
836 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
850 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
837 $ cat .hg/requires
851 $ cat .hg/requires
838 dotencode
852 dotencode
839 fncache
853 fncache
840 generaldelta
854 generaldelta
841 revlogv1
855 revlogv1
842 store
856 store
843 $ cd ..
857 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now