##// END OF EJS Templates
upgrade: write nodemap for manifests too...
Pulkit Goyal -
r47275:63685334 default
parent child Browse files
Show More
@@ -1,556 +1,563 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 manifest,
19 19 metadata,
20 20 pycompat,
21 21 requirements,
22 22 revlog,
23 23 scmutil,
24 24 util,
25 25 vfs as vfsmod,
26 26 )
27 27 from ..revlogutils import nodemap
28 28
29 29
30 30 def _revlogfrompath(repo, path):
31 31 """Obtain a revlog from a repo path.
32 32
33 33 An instance of the appropriate class is returned.
34 34 """
35 35 if path == b'00changelog.i':
36 36 return changelog.changelog(repo.svfs)
37 37 elif path.endswith(b'00manifest.i'):
38 38 mandir = path[: -len(b'00manifest.i')]
39 39 return manifest.manifestrevlog(repo.svfs, tree=mandir)
40 40 else:
41 41 # reverse of "/".join(("data", path + ".i"))
42 42 return filelog.filelog(repo.svfs, path[5:-2])
43 43
44 44
45 45 def _copyrevlog(tr, destrepo, oldrl, unencodedname):
46 46 """copy all relevant files for `oldrl` into `destrepo` store
47 47
48 48 Files are copied "as is" without any transformation. The copy is performed
49 49 without extra checks. Callers are responsible for making sure the copied
50 50 content is compatible with format of the destination repository.
51 51 """
52 52 oldrl = getattr(oldrl, '_revlog', oldrl)
53 53 newrl = _revlogfrompath(destrepo, unencodedname)
54 54 newrl = getattr(newrl, '_revlog', newrl)
55 55
56 56 oldvfs = oldrl.opener
57 57 newvfs = newrl.opener
58 58 oldindex = oldvfs.join(oldrl.indexfile)
59 59 newindex = newvfs.join(newrl.indexfile)
60 60 olddata = oldvfs.join(oldrl.datafile)
61 61 newdata = newvfs.join(newrl.datafile)
62 62
63 63 with newvfs(newrl.indexfile, b'w'):
64 64 pass # create all the directories
65 65
66 66 util.copyfile(oldindex, newindex)
67 67 copydata = oldrl.opener.exists(oldrl.datafile)
68 68 if copydata:
69 69 util.copyfile(olddata, newdata)
70 70
71 71 if not (
72 72 unencodedname.endswith(b'00changelog.i')
73 73 or unencodedname.endswith(b'00manifest.i')
74 74 ):
75 75 destrepo.svfs.fncache.add(unencodedname)
76 76 if copydata:
77 77 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
78 78
79 79
80 80 UPGRADE_CHANGELOG = b"changelog"
81 81 UPGRADE_MANIFEST = b"manifest"
82 82 UPGRADE_FILELOGS = b"all-filelogs"
83 83
84 84 UPGRADE_ALL_REVLOGS = frozenset(
85 85 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
86 86 )
87 87
88 88
89 89 def getsidedatacompanion(srcrepo, dstrepo):
90 90 sidedatacompanion = None
91 91 removedreqs = srcrepo.requirements - dstrepo.requirements
92 92 addedreqs = dstrepo.requirements - srcrepo.requirements
93 93 if requirements.SIDEDATA_REQUIREMENT in removedreqs:
94 94
95 95 def sidedatacompanion(rl, rev):
96 96 rl = getattr(rl, '_revlog', rl)
97 97 if rl.flags(rev) & revlog.REVIDX_SIDEDATA:
98 98 return True, (), {}, 0, 0
99 99 return False, (), {}, 0, 0
100 100
101 101 elif requirements.COPIESSDC_REQUIREMENT in addedreqs:
102 102 sidedatacompanion = metadata.getsidedataadder(srcrepo, dstrepo)
103 103 elif requirements.COPIESSDC_REQUIREMENT in removedreqs:
104 104 sidedatacompanion = metadata.getsidedataremover(srcrepo, dstrepo)
105 105 return sidedatacompanion
106 106
107 107
108 108 def matchrevlog(revlogfilter, entry):
109 109 """check if a revlog is selected for cloning.
110 110
111 111 In other words, are there any updates which need to be done on revlog
112 112 or it can be blindly copied.
113 113
114 114 The store entry is checked against the passed filter"""
115 115 if entry.endswith(b'00changelog.i'):
116 116 return UPGRADE_CHANGELOG in revlogfilter
117 117 elif entry.endswith(b'00manifest.i'):
118 118 return UPGRADE_MANIFEST in revlogfilter
119 119 return UPGRADE_FILELOGS in revlogfilter
120 120
121 121
122 122 def _perform_clone(
123 123 ui,
124 124 dstrepo,
125 125 tr,
126 126 old_revlog,
127 127 unencoded,
128 128 upgrade_op,
129 129 sidedatacompanion,
130 130 oncopiedrevision,
131 131 ):
132 132 """ returns the new revlog object created"""
133 133 newrl = None
134 134 if matchrevlog(upgrade_op.revlogs_to_process, unencoded):
135 135 ui.note(
136 136 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
137 137 )
138 138 newrl = _revlogfrompath(dstrepo, unencoded)
139 139 old_revlog.clone(
140 140 tr,
141 141 newrl,
142 142 addrevisioncb=oncopiedrevision,
143 143 deltareuse=upgrade_op.delta_reuse_mode,
144 144 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
145 145 sidedatacompanion=sidedatacompanion,
146 146 )
147 147 else:
148 148 msg = _(b'blindly copying %s containing %i revisions\n')
149 149 ui.note(msg % (unencoded, len(old_revlog)))
150 150 _copyrevlog(tr, dstrepo, old_revlog, unencoded)
151 151
152 152 newrl = _revlogfrompath(dstrepo, unencoded)
153 153 return newrl
154 154
155 155
156 156 def _clonerevlogs(
157 157 ui,
158 158 srcrepo,
159 159 dstrepo,
160 160 tr,
161 161 upgrade_op,
162 162 ):
163 163 """Copy revlogs between 2 repos."""
164 164 revcount = 0
165 165 srcsize = 0
166 166 srcrawsize = 0
167 167 dstsize = 0
168 168 fcount = 0
169 169 frevcount = 0
170 170 fsrcsize = 0
171 171 frawsize = 0
172 172 fdstsize = 0
173 173 mcount = 0
174 174 mrevcount = 0
175 175 msrcsize = 0
176 176 mrawsize = 0
177 177 mdstsize = 0
178 178 crevcount = 0
179 179 csrcsize = 0
180 180 crawsize = 0
181 181 cdstsize = 0
182 182
183 183 alldatafiles = list(srcrepo.store.walk())
184 184 # mapping of data files which needs to be cloned
185 185 # key is unencoded filename
186 186 # value is revlog_object_from_srcrepo
187 187 manifests = {}
188 188 changelogs = {}
189 189 filelogs = {}
190 190
191 191 # Perform a pass to collect metadata. This validates we can open all
192 192 # source files and allows a unified progress bar to be displayed.
193 193 for unencoded, encoded, size in alldatafiles:
194 194 if not unencoded.endswith(b'.i'):
195 195 continue
196 196
197 197 rl = _revlogfrompath(srcrepo, unencoded)
198 198
199 199 info = rl.storageinfo(
200 200 exclusivefiles=True,
201 201 revisionscount=True,
202 202 trackedsize=True,
203 203 storedsize=True,
204 204 )
205 205
206 206 revcount += info[b'revisionscount'] or 0
207 207 datasize = info[b'storedsize'] or 0
208 208 rawsize = info[b'trackedsize'] or 0
209 209
210 210 srcsize += datasize
211 211 srcrawsize += rawsize
212 212
213 213 # This is for the separate progress bars.
214 214 if isinstance(rl, changelog.changelog):
215 215 changelogs[unencoded] = rl
216 216 crevcount += len(rl)
217 217 csrcsize += datasize
218 218 crawsize += rawsize
219 219 elif isinstance(rl, manifest.manifestrevlog):
220 220 manifests[unencoded] = rl
221 221 mcount += 1
222 222 mrevcount += len(rl)
223 223 msrcsize += datasize
224 224 mrawsize += rawsize
225 225 elif isinstance(rl, filelog.filelog):
226 226 filelogs[unencoded] = rl
227 227 fcount += 1
228 228 frevcount += len(rl)
229 229 fsrcsize += datasize
230 230 frawsize += rawsize
231 231 else:
232 232 error.ProgrammingError(b'unknown revlog type')
233 233
234 234 if not revcount:
235 235 return
236 236
237 237 ui.status(
238 238 _(
239 239 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
240 240 b'%d in changelog)\n'
241 241 )
242 242 % (revcount, frevcount, mrevcount, crevcount)
243 243 )
244 244 ui.status(
245 245 _(b'migrating %s in store; %s tracked data\n')
246 246 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
247 247 )
248 248
249 249 # Used to keep track of progress.
250 250 progress = None
251 251
252 252 def oncopiedrevision(rl, rev, node):
253 253 progress.increment()
254 254
255 255 sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
256 256
257 257 # Migrating filelogs
258 258 ui.status(
259 259 _(
260 260 b'migrating %d filelogs containing %d revisions '
261 261 b'(%s in store; %s tracked data)\n'
262 262 )
263 263 % (
264 264 fcount,
265 265 frevcount,
266 266 util.bytecount(fsrcsize),
267 267 util.bytecount(frawsize),
268 268 )
269 269 )
270 270 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
271 271 for unencoded, oldrl in sorted(filelogs.items()):
272 272 newrl = _perform_clone(
273 273 ui,
274 274 dstrepo,
275 275 tr,
276 276 oldrl,
277 277 unencoded,
278 278 upgrade_op,
279 279 sidedatacompanion,
280 280 oncopiedrevision,
281 281 )
282 282 info = newrl.storageinfo(storedsize=True)
283 283 fdstsize += info[b'storedsize'] or 0
284 284 ui.status(
285 285 _(
286 286 b'finished migrating %d filelog revisions across %d '
287 287 b'filelogs; change in size: %s\n'
288 288 )
289 289 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
290 290 )
291 291
292 292 # Migrating manifests
293 293 ui.status(
294 294 _(
295 295 b'migrating %d manifests containing %d revisions '
296 296 b'(%s in store; %s tracked data)\n'
297 297 )
298 298 % (
299 299 mcount,
300 300 mrevcount,
301 301 util.bytecount(msrcsize),
302 302 util.bytecount(mrawsize),
303 303 )
304 304 )
305 305 if progress:
306 306 progress.complete()
307 307 progress = srcrepo.ui.makeprogress(
308 308 _(b'manifest revisions'), total=mrevcount
309 309 )
310 310 for unencoded, oldrl in sorted(manifests.items()):
311 311 newrl = _perform_clone(
312 312 ui,
313 313 dstrepo,
314 314 tr,
315 315 oldrl,
316 316 unencoded,
317 317 upgrade_op,
318 318 sidedatacompanion,
319 319 oncopiedrevision,
320 320 )
321 321 info = newrl.storageinfo(storedsize=True)
322 322 mdstsize += info[b'storedsize'] or 0
323 323 ui.status(
324 324 _(
325 325 b'finished migrating %d manifest revisions across %d '
326 326 b'manifests; change in size: %s\n'
327 327 )
328 328 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
329 329 )
330 330
331 331 # Migrating changelog
332 332 ui.status(
333 333 _(
334 334 b'migrating changelog containing %d revisions '
335 335 b'(%s in store; %s tracked data)\n'
336 336 )
337 337 % (
338 338 crevcount,
339 339 util.bytecount(csrcsize),
340 340 util.bytecount(crawsize),
341 341 )
342 342 )
343 343 if progress:
344 344 progress.complete()
345 345 progress = srcrepo.ui.makeprogress(
346 346 _(b'changelog revisions'), total=crevcount
347 347 )
348 348 for unencoded, oldrl in sorted(changelogs.items()):
349 349 newrl = _perform_clone(
350 350 ui,
351 351 dstrepo,
352 352 tr,
353 353 oldrl,
354 354 unencoded,
355 355 upgrade_op,
356 356 sidedatacompanion,
357 357 oncopiedrevision,
358 358 )
359 359 info = newrl.storageinfo(storedsize=True)
360 360 cdstsize += info[b'storedsize'] or 0
361 361 progress.complete()
362 362 ui.status(
363 363 _(
364 364 b'finished migrating %d changelog revisions; change in size: '
365 365 b'%s\n'
366 366 )
367 367 % (crevcount, util.bytecount(cdstsize - csrcsize))
368 368 )
369 369
370 370 dstsize = fdstsize + mdstsize + cdstsize
371 371 ui.status(
372 372 _(
373 373 b'finished migrating %d total revisions; total change in store '
374 374 b'size: %s\n'
375 375 )
376 376 % (revcount, util.bytecount(dstsize - srcsize))
377 377 )
378 378
379 379
380 380 def _files_to_copy_post_revlog_clone(srcrepo):
381 381 """yields files which should be copied to destination after revlogs
382 382 are cloned"""
383 383 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
384 384 # don't copy revlogs as they are already cloned
385 385 if path.endswith((b'.i', b'.d', b'.n', b'.nd')):
386 386 continue
387 387 # Skip transaction related files.
388 388 if path.startswith(b'undo'):
389 389 continue
390 390 # Only copy regular files.
391 391 if kind != stat.S_IFREG:
392 392 continue
393 393 # Skip other skipped files.
394 394 if path in (b'lock', b'fncache'):
395 395 continue
396 396 # TODO: should we skip cache too?
397 397
398 398 yield path
399 399
400 400
401 401 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
402 402 """Replace the stores after current repository is upgraded
403 403
404 404 Creates a backup of current repository store at backup path
405 405 Replaces upgraded store files in current repo from upgraded one
406 406
407 407 Arguments:
408 408 currentrepo: repo object of current repository
409 409 upgradedrepo: repo object of the upgraded data
410 410 backupvfs: vfs object for the backup path
411 411 upgrade_op: upgrade operation object
412 412 to be used to decide what all is upgraded
413 413 """
414 414 # TODO: don't blindly rename everything in store
415 415 # There can be upgrades where store is not touched at all
416 416 if upgrade_op.backup_store:
417 417 util.rename(currentrepo.spath, backupvfs.join(b'store'))
418 418 else:
419 419 currentrepo.vfs.rmtree(b'store', forcibly=True)
420 420 util.rename(upgradedrepo.spath, currentrepo.spath)
421 421
422 422
423 423 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
424 424 """Hook point for extensions to perform additional actions during upgrade.
425 425
426 426 This function is called after revlogs and store files have been copied but
427 427 before the new store is swapped into the original location.
428 428 """
429 429
430 430
431 431 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
432 432 """Do the low-level work of upgrading a repository.
433 433
434 434 The upgrade is effectively performed as a copy between a source
435 435 repository and a temporary destination repository.
436 436
437 437 The source repository is unmodified for as long as possible so the
438 438 upgrade can abort at any time without causing loss of service for
439 439 readers and without corrupting the source repository.
440 440 """
441 441 assert srcrepo.currentwlock()
442 442 assert dstrepo.currentwlock()
443 443 backuppath = None
444 444 backupvfs = None
445 445
446 446 ui.status(
447 447 _(
448 448 b'(it is safe to interrupt this process any time before '
449 449 b'data migration completes)\n'
450 450 )
451 451 )
452 452
453 453 if upgrade_op.requirements_only:
454 454 ui.status(_(b'upgrading repository requirements\n'))
455 455 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
456 456 # if there is only one action and that is persistent nodemap upgrade
457 457 # directly write the nodemap file and update requirements instead of going
458 458 # through the whole cloning process
459 459 elif (
460 460 len(upgrade_op.upgrade_actions) == 1
461 461 and b'persistent-nodemap' in upgrade_op._upgrade_actions_names
462 462 and not upgrade_op.removed_actions
463 463 ):
464 464 ui.status(
465 465 _(b'upgrading repository to use persistent nodemap feature\n')
466 466 )
467 467 with srcrepo.transaction(b'upgrade') as tr:
468 468 unfi = srcrepo.unfiltered()
469 469 cl = unfi.changelog
470 470 nodemap.persist_nodemap(tr, cl, force=True)
471 # we want to directly operate on the underlying revlog to force
472 # create a nodemap file. This is fine since this is upgrade code
473 # and it heavily relies on repository being revlog based
474 # hence accessing private attributes can be justified
475 nodemap.persist_nodemap(
476 tr, unfi.manifestlog._rootstore._revlog, force=True
477 )
471 478 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
472 479 else:
473 480 with dstrepo.transaction(b'upgrade') as tr:
474 481 _clonerevlogs(
475 482 ui,
476 483 srcrepo,
477 484 dstrepo,
478 485 tr,
479 486 upgrade_op,
480 487 )
481 488
482 489 # Now copy other files in the store directory.
483 490 for p in _files_to_copy_post_revlog_clone(srcrepo):
484 491 srcrepo.ui.status(_(b'copying %s\n') % p)
485 492 src = srcrepo.store.rawvfs.join(p)
486 493 dst = dstrepo.store.rawvfs.join(p)
487 494 util.copyfile(src, dst, copystat=True)
488 495
489 496 finishdatamigration(ui, srcrepo, dstrepo, requirements)
490 497
491 498 ui.status(_(b'data fully upgraded in a temporary repository\n'))
492 499
493 500 if upgrade_op.backup_store:
494 501 backuppath = pycompat.mkdtemp(
495 502 prefix=b'upgradebackup.', dir=srcrepo.path
496 503 )
497 504 backupvfs = vfsmod.vfs(backuppath)
498 505
499 506 # Make a backup of requires file first, as it is the first to be modified.
500 507 util.copyfile(
501 508 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
502 509 )
503 510
504 511 # We install an arbitrary requirement that clients must not support
505 512 # as a mechanism to lock out new clients during the data swap. This is
506 513 # better than allowing a client to continue while the repository is in
507 514 # an inconsistent state.
508 515 ui.status(
509 516 _(
510 517 b'marking source repository as being upgraded; clients will be '
511 518 b'unable to read from repository\n'
512 519 )
513 520 )
514 521 scmutil.writereporequirements(
515 522 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
516 523 )
517 524
518 525 ui.status(_(b'starting in-place swap of repository data\n'))
519 526 if upgrade_op.backup_store:
520 527 ui.status(
521 528 _(b'replaced files will be backed up at %s\n') % backuppath
522 529 )
523 530
524 531 # Now swap in the new store directory. Doing it as a rename should make
525 532 # the operation nearly instantaneous and atomic (at least in well-behaved
526 533 # environments).
527 534 ui.status(_(b'replacing store...\n'))
528 535 tstart = util.timer()
529 536 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
530 537 elapsed = util.timer() - tstart
531 538 ui.status(
532 539 _(
533 540 b'store replacement complete; repository was inconsistent for '
534 541 b'%0.1fs\n'
535 542 )
536 543 % elapsed
537 544 )
538 545
539 546 # We first write the requirements file. Any new requirements will lock
540 547 # out legacy clients.
541 548 ui.status(
542 549 _(
543 550 b'finalizing requirements file and making repository readable '
544 551 b'again\n'
545 552 )
546 553 )
547 554 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
548 555
549 556 if upgrade_op.backup_store:
550 557 # The lock file from the old store won't be removed because nothing has a
551 558 # reference to its new location. So clean it up manually. Alternatively, we
552 559 # could update srcrepo.svfs and other variables to point to the new
553 560 # location. This is simpler.
554 561 backupvfs.unlink(b'store/lock')
555 562
556 563 return backuppath
@@ -1,751 +1,753 b''
1 1 ===================================
2 2 Test the persistent on-disk nodemap
3 3 ===================================
4 4
5 5 $ cat << EOF >> $HGRCPATH
6 6 > [format]
7 7 > use-persistent-nodemap=yes
8 8 > [devel]
9 9 > persistent-nodemap=yes
10 10 > EOF
11 11
12 12 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
13 13 $ cd test-repo
14 14
15 15 Check handling of the default slow-path value
16 16
17 17 #if no-pure no-rust
18 18
19 19 $ hg id
20 20 abort: accessing `persistent-nodemap` repository without associated fast implementation.
21 21 (check `hg help config.format.use-persistent-nodemap` for details)
22 22 [255]
23 23
24 24 Unlock further check (we are here to test the feature)
25 25
26 26 $ cat << EOF >> $HGRCPATH
27 27 > [storage]
28 28 > # to avoid spamming the test
29 29 > revlog.persistent-nodemap.slow-path=allow
30 30 > EOF
31 31
32 32 #endif
33 33
34 34 #if rust
35 35
36 36 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
37 37 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
38 38 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
39 39 incorrectly used `libc::c_int` (32 bits).
40 40 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
41 41
42 42 $ hg log -r 00000000
43 43 changeset: -1:000000000000
44 44 tag: tip
45 45 user:
46 46 date: Thu Jan 01 00:00:00 1970 +0000
47 47
48 48
49 49 #endif
50 50
51 51
52 52 $ hg debugformat
53 53 format-variant repo
54 54 fncache: yes
55 55 dotencode: yes
56 56 generaldelta: yes
57 57 share-safe: no
58 58 sparserevlog: yes
59 59 sidedata: no
60 60 persistent-nodemap: yes
61 61 copies-sdc: no
62 62 plain-cl-delta: yes
63 63 compression: zlib
64 64 compression-level: default
65 65 $ hg debugbuilddag .+5000 --new-file
66 66
67 67 $ hg debugnodemap --metadata
68 68 uid: ???????????????? (glob)
69 69 tip-rev: 5000
70 70 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
71 71 data-length: 121088
72 72 data-unused: 0
73 73 data-unused: 0.000%
74 74 $ f --size .hg/store/00changelog.n
75 75 .hg/store/00changelog.n: size=70
76 76
77 77 Simple lookup works
78 78
79 79 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
80 80 $ hg log -r "$ANYNODE" --template '{rev}\n'
81 81 5000
82 82
83 83
84 84 #if rust
85 85
86 86 $ f --sha256 .hg/store/00changelog-*.nd
87 87 .hg/store/00changelog-????????????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
88 88
89 89 $ f --sha256 .hg/store/00manifest-*.nd
90 90 .hg/store/00manifest-????????????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
91 91 $ hg debugnodemap --dump-new | f --sha256 --size
92 92 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
93 93 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
94 94 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
95 95 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
96 96 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
97 97 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
98 98 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
99 99 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
100 100 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
101 101 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
102 102 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
103 103 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
104 104 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
105 105 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
106 106 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
107 107 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
108 108 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
109 109 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
110 110 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
111 111
112 112
113 113 #else
114 114
115 115 $ f --sha256 .hg/store/00changelog-*.nd
116 116 .hg/store/00changelog-????????????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
117 117 $ hg debugnodemap --dump-new | f --sha256 --size
118 118 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
119 119 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
120 120 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
121 121 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
122 122 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
123 123 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
124 124 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
125 125 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
126 126 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
127 127 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
128 128 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
129 129 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
130 130 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
131 131 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
132 132 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
133 133 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
134 134 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
135 135 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
136 136 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
137 137
138 138 #endif
139 139
140 140 $ hg debugnodemap --check
141 141 revision in index: 5001
142 142 revision in nodemap: 5001
143 143
144 144 add a new commit
145 145
146 146 $ hg up
147 147 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 148 $ echo foo > foo
149 149 $ hg add foo
150 150
151 151
152 152 Check slow-path config value handling
153 153 -------------------------------------
154 154
155 155 #if no-pure no-rust
156 156
157 157 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
158 158 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
159 159 falling back to default value: abort
160 160 abort: accessing `persistent-nodemap` repository without associated fast implementation.
161 161 (check `hg help config.format.use-persistent-nodemap` for details)
162 162 [255]
163 163
164 164 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
165 165 warning: accessing `persistent-nodemap` repository without associated fast implementation.
166 166 (check `hg help config.format.use-persistent-nodemap` for details)
167 167 changeset: 5000:6b02b8c7b966
168 168 tag: tip
169 169 user: debugbuilddag
170 170 date: Thu Jan 01 01:23:20 1970 +0000
171 171 summary: r5000
172 172
173 173 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
174 174 abort: accessing `persistent-nodemap` repository without associated fast implementation.
175 175 (check `hg help config.format.use-persistent-nodemap` for details)
176 176 [255]
177 177
178 178 #else
179 179
180 180 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
181 181 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
182 182 falling back to default value: abort
183 183 6b02b8c7b966+ tip
184 184
185 185 #endif
186 186
187 187 $ hg ci -m 'foo'
188 188
189 189 #if no-pure no-rust
190 190 $ hg debugnodemap --metadata
191 191 uid: ???????????????? (glob)
192 192 tip-rev: 5001
193 193 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
194 194 data-length: 121088
195 195 data-unused: 0
196 196 data-unused: 0.000%
197 197 #else
198 198 $ hg debugnodemap --metadata
199 199 uid: ???????????????? (glob)
200 200 tip-rev: 5001
201 201 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
202 202 data-length: 121344
203 203 data-unused: 256
204 204 data-unused: 0.211%
205 205 #endif
206 206
207 207 $ f --size .hg/store/00changelog.n
208 208 .hg/store/00changelog.n: size=70
209 209
210 210 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
211 211
212 212 #if pure
213 213 $ f --sha256 .hg/store/00changelog-*.nd --size
214 214 .hg/store/00changelog-????????????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
215 215 #endif
216 216
217 217 #if rust
218 218 $ f --sha256 .hg/store/00changelog-*.nd --size
219 219 .hg/store/00changelog-????????????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
220 220 #endif
221 221
222 222 #if no-pure no-rust
223 223 $ f --sha256 .hg/store/00changelog-*.nd --size
224 224 .hg/store/00changelog-????????????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
225 225 #endif
226 226
227 227 $ hg debugnodemap --check
228 228 revision in index: 5002
229 229 revision in nodemap: 5002
230 230
231 231 Test code path without mmap
232 232 ---------------------------
233 233
234 234 $ echo bar > bar
235 235 $ hg add bar
236 236 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
237 237
238 238 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
239 239 revision in index: 5003
240 240 revision in nodemap: 5003
241 241 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
242 242 revision in index: 5003
243 243 revision in nodemap: 5003
244 244
245 245
246 246 #if pure
247 247 $ hg debugnodemap --metadata
248 248 uid: ???????????????? (glob)
249 249 tip-rev: 5002
250 250 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
251 251 data-length: 121600
252 252 data-unused: 512
253 253 data-unused: 0.421%
254 254 $ f --sha256 .hg/store/00changelog-*.nd --size
255 255 .hg/store/00changelog-????????????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
256 256 #endif
257 257 #if rust
258 258 $ hg debugnodemap --metadata
259 259 uid: ???????????????? (glob)
260 260 tip-rev: 5002
261 261 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
262 262 data-length: 121600
263 263 data-unused: 512
264 264 data-unused: 0.421%
265 265 $ f --sha256 .hg/store/00changelog-*.nd --size
266 266 .hg/store/00changelog-????????????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
267 267 #endif
268 268 #if no-pure no-rust
269 269 $ hg debugnodemap --metadata
270 270 uid: ???????????????? (glob)
271 271 tip-rev: 5002
272 272 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
273 273 data-length: 121088
274 274 data-unused: 0
275 275 data-unused: 0.000%
276 276 $ f --sha256 .hg/store/00changelog-*.nd --size
277 277 .hg/store/00changelog-????????????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
278 278 #endif
279 279
280 280 Test force warming the cache
281 281
282 282 $ rm .hg/store/00changelog.n
283 283 $ hg debugnodemap --metadata
284 284 $ hg debugupdatecache
285 285 #if pure
286 286 $ hg debugnodemap --metadata
287 287 uid: ???????????????? (glob)
288 288 tip-rev: 5002
289 289 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
290 290 data-length: 121088
291 291 data-unused: 0
292 292 data-unused: 0.000%
293 293 #else
294 294 $ hg debugnodemap --metadata
295 295 uid: ???????????????? (glob)
296 296 tip-rev: 5002
297 297 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
298 298 data-length: 121088
299 299 data-unused: 0
300 300 data-unused: 0.000%
301 301 #endif
302 302
303 303 Check out of sync nodemap
304 304 =========================
305 305
306 306 First copy old data on the side.
307 307
308 308 $ mkdir ../tmp-copies
309 309 $ cp .hg/store/00changelog-????????????????.nd .hg/store/00changelog.n ../tmp-copies
310 310
311 311 Nodemap lagging behind
312 312 ----------------------
313 313
314 314 make a new commit
315 315
316 316 $ echo bar2 > bar
317 317 $ hg ci -m 'bar2'
318 318 $ NODE=`hg log -r tip -T '{node}\n'`
319 319 $ hg log -r "$NODE" -T '{rev}\n'
320 320 5003
321 321
322 322 If the nodemap is lagging behind, it can catch up fine
323 323
324 324 $ hg debugnodemap --metadata
325 325 uid: ???????????????? (glob)
326 326 tip-rev: 5003
327 327 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
328 328 data-length: 121344 (pure !)
329 329 data-length: 121344 (rust !)
330 330 data-length: 121152 (no-rust no-pure !)
331 331 data-unused: 192 (pure !)
332 332 data-unused: 192 (rust !)
333 333 data-unused: 0 (no-rust no-pure !)
334 334 data-unused: 0.158% (pure !)
335 335 data-unused: 0.158% (rust !)
336 336 data-unused: 0.000% (no-rust no-pure !)
337 337 $ cp -f ../tmp-copies/* .hg/store/
338 338 $ hg debugnodemap --metadata
339 339 uid: ???????????????? (glob)
340 340 tip-rev: 5002
341 341 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
342 342 data-length: 121088
343 343 data-unused: 0
344 344 data-unused: 0.000%
345 345 $ hg log -r "$NODE" -T '{rev}\n'
346 346 5003
347 347
348 348 changelog altered
349 349 -----------------
350 350
351 351 If the nodemap is not gated behind a requirements, an unaware client can alter
352 352 the repository so the revlog used to generate the nodemap is not longer
353 353 compatible with the persistent nodemap. We need to detect that.
354 354
355 355 $ hg up "$NODE~5"
356 356 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
357 357 $ echo bar > babar
358 358 $ hg add babar
359 359 $ hg ci -m 'babar'
360 360 created new head
361 361 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
362 362 $ hg log -r "$OTHERNODE" -T '{rev}\n'
363 363 5004
364 364
365 365 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
366 366
367 367 the nodemap should detect the changelog have been tampered with and recover.
368 368
369 369 $ hg debugnodemap --metadata
370 370 uid: ???????????????? (glob)
371 371 tip-rev: 5002
372 372 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
373 373 data-length: 121536 (pure !)
374 374 data-length: 121088 (rust !)
375 375 data-length: 121088 (no-pure no-rust !)
376 376 data-unused: 448 (pure !)
377 377 data-unused: 0 (rust !)
378 378 data-unused: 0 (no-pure no-rust !)
379 379 data-unused: 0.000% (rust !)
380 380 data-unused: 0.369% (pure !)
381 381 data-unused: 0.000% (no-pure no-rust !)
382 382
383 383 $ cp -f ../tmp-copies/* .hg/store/
384 384 $ hg debugnodemap --metadata
385 385 uid: ???????????????? (glob)
386 386 tip-rev: 5002
387 387 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
388 388 data-length: 121088
389 389 data-unused: 0
390 390 data-unused: 0.000%
391 391 $ hg log -r "$OTHERNODE" -T '{rev}\n'
392 392 5002
393 393
394 394 missing data file
395 395 -----------------
396 396
397 397 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
398 398 > sed 's/uid: //'`
399 399 $ FILE=.hg/store/00changelog-"${UUID}".nd
400 400 $ mv $FILE ../tmp-data-file
401 401 $ cp .hg/store/00changelog.n ../tmp-docket
402 402
403 403 mercurial don't crash
404 404
405 405 $ hg log -r .
406 406 changeset: 5002:b355ef8adce0
407 407 tag: tip
408 408 parent: 4998:d918ad6d18d3
409 409 user: test
410 410 date: Thu Jan 01 00:00:00 1970 +0000
411 411 summary: babar
412 412
413 413 $ hg debugnodemap --metadata
414 414
415 415 $ hg debugupdatecache
416 416 $ hg debugnodemap --metadata
417 417 uid: * (glob)
418 418 tip-rev: 5002
419 419 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
420 420 data-length: 121088
421 421 data-unused: 0
422 422 data-unused: 0.000%
423 423 $ mv ../tmp-data-file $FILE
424 424 $ mv ../tmp-docket .hg/store/00changelog.n
425 425
426 426 Check transaction related property
427 427 ==================================
428 428
429 429 An up to date nodemap should be available to shell hooks,
430 430
431 431 $ echo dsljfl > a
432 432 $ hg add a
433 433 $ hg ci -m a
434 434 $ hg debugnodemap --metadata
435 435 uid: ???????????????? (glob)
436 436 tip-rev: 5003
437 437 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
438 438 data-length: 121088
439 439 data-unused: 0
440 440 data-unused: 0.000%
441 441 $ echo babar2 > babar
442 442 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
443 443 uid: ???????????????? (glob)
444 444 tip-rev: 5004
445 445 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
446 446 data-length: 121280 (pure !)
447 447 data-length: 121280 (rust !)
448 448 data-length: 121088 (no-pure no-rust !)
449 449 data-unused: 192 (pure !)
450 450 data-unused: 192 (rust !)
451 451 data-unused: 0 (no-pure no-rust !)
452 452 data-unused: 0.158% (pure !)
453 453 data-unused: 0.158% (rust !)
454 454 data-unused: 0.000% (no-pure no-rust !)
455 455 $ hg debugnodemap --metadata
456 456 uid: ???????????????? (glob)
457 457 tip-rev: 5004
458 458 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
459 459 data-length: 121280 (pure !)
460 460 data-length: 121280 (rust !)
461 461 data-length: 121088 (no-pure no-rust !)
462 462 data-unused: 192 (pure !)
463 463 data-unused: 192 (rust !)
464 464 data-unused: 0 (no-pure no-rust !)
465 465 data-unused: 0.158% (pure !)
466 466 data-unused: 0.158% (rust !)
467 467 data-unused: 0.000% (no-pure no-rust !)
468 468
469 469 Another process does not see the pending nodemap content during run.
470 470
471 471 $ PATH=$RUNTESTDIR/testlib/:$PATH
472 472 $ echo qpoasp > a
473 473 $ hg ci -m a2 \
474 474 > --config "hooks.pretxnclose=wait-on-file 20 sync-repo-read sync-txn-pending" \
475 475 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
476 476
477 477 (read the repository while the commit transaction is pending)
478 478
479 479 $ wait-on-file 20 sync-txn-pending && \
480 480 > hg debugnodemap --metadata && \
481 481 > wait-on-file 20 sync-txn-close sync-repo-read
482 482 uid: ???????????????? (glob)
483 483 tip-rev: 5004
484 484 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
485 485 data-length: 121280 (pure !)
486 486 data-length: 121280 (rust !)
487 487 data-length: 121088 (no-pure no-rust !)
488 488 data-unused: 192 (pure !)
489 489 data-unused: 192 (rust !)
490 490 data-unused: 0 (no-pure no-rust !)
491 491 data-unused: 0.158% (pure !)
492 492 data-unused: 0.158% (rust !)
493 493 data-unused: 0.000% (no-pure no-rust !)
494 494 $ hg debugnodemap --metadata
495 495 uid: ???????????????? (glob)
496 496 tip-rev: 5005
497 497 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
498 498 data-length: 121536 (pure !)
499 499 data-length: 121536 (rust !)
500 500 data-length: 121088 (no-pure no-rust !)
501 501 data-unused: 448 (pure !)
502 502 data-unused: 448 (rust !)
503 503 data-unused: 0 (no-pure no-rust !)
504 504 data-unused: 0.369% (pure !)
505 505 data-unused: 0.369% (rust !)
506 506 data-unused: 0.000% (no-pure no-rust !)
507 507
508 508 $ cat output.txt
509 509
510 510 Check that a failing transaction will properly revert the data
511 511
512 512 $ echo plakfe > a
513 513 $ f --size --sha256 .hg/store/00changelog-*.nd
514 514 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
515 515 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
516 516 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
517 517 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
518 518 transaction abort!
519 519 rollback completed
520 520 abort: This is a late abort
521 521 [255]
522 522 $ hg debugnodemap --metadata
523 523 uid: ???????????????? (glob)
524 524 tip-rev: 5005
525 525 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
526 526 data-length: 121536 (pure !)
527 527 data-length: 121536 (rust !)
528 528 data-length: 121088 (no-pure no-rust !)
529 529 data-unused: 448 (pure !)
530 530 data-unused: 448 (rust !)
531 531 data-unused: 0 (no-pure no-rust !)
532 532 data-unused: 0.369% (pure !)
533 533 data-unused: 0.369% (rust !)
534 534 data-unused: 0.000% (no-pure no-rust !)
535 535 $ f --size --sha256 .hg/store/00changelog-*.nd
536 536 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
537 537 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
538 538 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
539 539
540 540 Check that removing content does not confuse the nodemap
541 541 --------------------------------------------------------
542 542
543 543 removing data with rollback
544 544
545 545 $ echo aso > a
546 546 $ hg ci -m a4
547 547 $ hg rollback
548 548 repository tip rolled back to revision 5005 (undo commit)
549 549 working directory now based on revision 5005
550 550 $ hg id -r .
551 551 90d5d3ba2fc4 tip
552 552
553 553 roming data with strip
554 554
555 555 $ echo aso > a
556 556 $ hg ci -m a4
557 557 $ hg --config extensions.strip= strip -r . --no-backup
558 558 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
559 559 $ hg id -r . --traceback
560 560 90d5d3ba2fc4 tip
561 561
562 562 Test upgrade / downgrade
563 563 ========================
564 564
565 565 downgrading
566 566
567 567 $ cat << EOF >> .hg/hgrc
568 568 > [format]
569 569 > use-persistent-nodemap=no
570 570 > EOF
571 571 $ hg debugformat -v
572 572 format-variant repo config default
573 573 fncache: yes yes yes
574 574 dotencode: yes yes yes
575 575 generaldelta: yes yes yes
576 576 share-safe: no no no
577 577 sparserevlog: yes yes yes
578 578 sidedata: no no no
579 579 persistent-nodemap: yes no no
580 580 copies-sdc: no no no
581 581 plain-cl-delta: yes yes yes
582 582 compression: zlib zlib zlib
583 583 compression-level: default default default
584 584 $ hg debugupgraderepo --run --no-backup --quiet
585 585 upgrade will perform the following actions:
586 586
587 587 requirements
588 588 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
589 589 removed: persistent-nodemap
590 590
591 591 processed revlogs:
592 592 - all-filelogs
593 593 - changelog
594 594 - manifest
595 595
596 596 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
597 597 [1]
598 598 $ hg debugnodemap --metadata
599 599
600 600
601 601 upgrading
602 602
603 603 $ cat << EOF >> .hg/hgrc
604 604 > [format]
605 605 > use-persistent-nodemap=yes
606 606 > EOF
607 607 $ hg debugformat -v
608 608 format-variant repo config default
609 609 fncache: yes yes yes
610 610 dotencode: yes yes yes
611 611 generaldelta: yes yes yes
612 612 share-safe: no no no
613 613 sparserevlog: yes yes yes
614 614 sidedata: no no no
615 615 persistent-nodemap: no yes no
616 616 copies-sdc: no no no
617 617 plain-cl-delta: yes yes yes
618 618 compression: zlib zlib zlib
619 619 compression-level: default default default
620 620 $ hg debugupgraderepo --run --no-backup
621 621 upgrade will perform the following actions:
622 622
623 623 requirements
624 624 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
625 625 added: persistent-nodemap
626 626
627 627 persistent-nodemap
628 628 Speedup revision lookup by node id.
629 629
630 630 processed revlogs:
631 631 - all-filelogs
632 632 - changelog
633 633 - manifest
634 634
635 635 beginning upgrade...
636 636 repository locked and read-only
637 637 creating temporary repository to stage upgraded data: $TESTTMP/test-repo/.hg/upgrade.* (glob)
638 638 (it is safe to interrupt this process any time before data migration completes)
639 639 upgrading repository to use persistent nodemap feature
640 640 removing temporary repository $TESTTMP/test-repo/.hg/upgrade.* (glob)
641 641 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
642 642 00changelog-*.nd (glob)
643 643 00changelog.n
644 00manifest-*.nd (glob)
645 00manifest.n
644 646
645 647 $ hg debugnodemap --metadata
646 648 uid: * (glob)
647 649 tip-rev: 5005
648 650 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
649 651 data-length: 121088
650 652 data-unused: 0
651 653 data-unused: 0.000%
652 654
653 655 Running unrelated upgrade
654 656
655 657 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
656 658 upgrade will perform the following actions:
657 659
658 660 requirements
659 661 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, sparserevlog, store
660 662
661 663 optimisations: re-delta-all
662 664
663 665 processed revlogs:
664 666 - all-filelogs
665 667 - changelog
666 668 - manifest
667 669
668 670 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
669 671 00changelog-*.nd (glob)
670 672 00changelog.n
671 673 00manifest-*.nd (glob)
672 674 00manifest.n
673 675
674 676 $ hg debugnodemap --metadata
675 677 uid: * (glob)
676 678 tip-rev: 5005
677 679 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
678 680 data-length: 121088
679 681 data-unused: 0
680 682 data-unused: 0.000%
681 683
682 684 Persistent nodemap and local/streaming clone
683 685 ============================================
684 686
685 687 $ cd ..
686 688
687 689 standard clone
688 690 --------------
689 691
690 692 The persistent nodemap should exist after a streaming clone
691 693
692 694 $ hg clone --pull --quiet -U test-repo standard-clone
693 695 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
694 696 00changelog-*.nd (glob)
695 697 00changelog.n
696 698 00manifest-*.nd (glob)
697 699 00manifest.n
698 700 $ hg -R standard-clone debugnodemap --metadata
699 701 uid: * (glob)
700 702 tip-rev: 5005
701 703 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
702 704 data-length: 121088
703 705 data-unused: 0
704 706 data-unused: 0.000%
705 707
706 708
707 709 local clone
708 710 ------------
709 711
710 712 The persistent nodemap should exist after a streaming clone
711 713
712 714 $ hg clone -U test-repo local-clone
713 715 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
714 716 00changelog-*.nd (glob)
715 717 00changelog.n
716 718 00manifest-*.nd (glob)
717 719 00manifest.n
718 720 $ hg -R local-clone debugnodemap --metadata
719 721 uid: * (glob)
720 722 tip-rev: 5005
721 723 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
722 724 data-length: 121088
723 725 data-unused: 0
724 726 data-unused: 0.000%
725 727
726 728 stream clone
727 729 ------------
728 730
729 731 The persistent nodemap should exist after a streaming clone
730 732
731 733 $ hg clone -U --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
732 734 adding [s] 00manifest.n (70 bytes)
733 735 adding [s] 00manifest.i (313 KB)
734 736 adding [s] 00manifest.d (452 KB)
735 737 adding [s] 00manifest-*.nd (118 KB) (glob)
736 738 adding [s] 00changelog.n (70 bytes)
737 739 adding [s] 00changelog.i (313 KB)
738 740 adding [s] 00changelog.d (360 KB)
739 741 adding [s] 00changelog-*.nd (118 KB) (glob)
740 742 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
741 743 00changelog-*.nd (glob)
742 744 00changelog.n
743 745 00manifest-*.nd (glob)
744 746 00manifest.n
745 747 $ hg -R stream-clone debugnodemap --metadata
746 748 uid: * (glob)
747 749 tip-rev: 5005
748 750 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
749 751 data-length: 121088
750 752 data-unused: 0
751 753 data-unused: 0.000%
General Comments 0
You need to be logged in to leave comments. Login now