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