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