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