Show More
@@ -2987,10 +2987,22 b' def debugrebuilddirstate(ui, repo, rev, ' | |||||
2987 | dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles) |
|
2987 | dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles) | |
2988 |
|
2988 | |||
2989 |
|
2989 | |||
2990 | @command(b'debugrebuildfncache', [], b'') |
|
2990 | @command( | |
2991 |
|
|
2991 | b'debugrebuildfncache', | |
|
2992 | [ | |||
|
2993 | ( | |||
|
2994 | b'', | |||
|
2995 | b'only-data', | |||
|
2996 | False, | |||
|
2997 | _(b'only look for wrong .d files (much faster)'), | |||
|
2998 | ) | |||
|
2999 | ], | |||
|
3000 | b'', | |||
|
3001 | ) | |||
|
3002 | def debugrebuildfncache(ui, repo, **opts): | |||
2992 | """rebuild the fncache file""" |
|
3003 | """rebuild the fncache file""" | |
2993 | repair.rebuildfncache(ui, repo) |
|
3004 | opts = pycompat.byteskwargs(opts) | |
|
3005 | repair.rebuildfncache(ui, repo, opts.get(b"only_data")) | |||
2994 |
|
3006 | |||
2995 |
|
3007 | |||
2996 | @command( |
|
3008 | @command( |
@@ -441,7 +441,7 b' def manifestrevlogs(repo):' | |||||
441 | yield repo.manifestlog.getstorage(dir) |
|
441 | yield repo.manifestlog.getstorage(dir) | |
442 |
|
442 | |||
443 |
|
443 | |||
444 | def rebuildfncache(ui, repo): |
|
444 | def rebuildfncache(ui, repo, only_data=False): | |
445 | """Rebuilds the fncache file from repo history. |
|
445 | """Rebuilds the fncache file from repo history. | |
446 |
|
446 | |||
447 | Missing entries will be added. Extra entries will be removed. |
|
447 | Missing entries will be added. Extra entries will be removed. | |
@@ -465,28 +465,40 b' def rebuildfncache(ui, repo):' | |||||
465 | newentries = set() |
|
465 | newentries = set() | |
466 | seenfiles = set() |
|
466 | seenfiles = set() | |
467 |
|
467 | |||
468 | progress = ui.makeprogress( |
|
468 | if only_data: | |
469 | _(b'rebuilding'), unit=_(b'changesets'), total=len(repo) |
|
469 | # Trust the listing of .i from the fncache, but not the .d. This is | |
470 | ) |
|
470 | # much faster, because we only need to stat every possible .d files, | |
471 | for rev in repo: |
|
471 | # instead of reading the full changelog | |
472 | progress.update(rev) |
|
472 | for f in fnc: | |
|
473 | if f[:5] == b'data/' and f[-2:] == b'.i': | |||
|
474 | seenfiles.add(f[5:-2]) | |||
|
475 | newentries.add(f) | |||
|
476 | dataf = f[:-2] + b'.d' | |||
|
477 | if repo.store._exists(dataf): | |||
|
478 | newentries.add(dataf) | |||
|
479 | else: | |||
|
480 | progress = ui.makeprogress( | |||
|
481 | _(b'rebuilding'), unit=_(b'changesets'), total=len(repo) | |||
|
482 | ) | |||
|
483 | for rev in repo: | |||
|
484 | progress.update(rev) | |||
473 |
|
485 | |||
474 | ctx = repo[rev] |
|
486 | ctx = repo[rev] | |
475 | for f in ctx.files(): |
|
487 | for f in ctx.files(): | |
476 | # This is to minimize I/O. |
|
488 | # This is to minimize I/O. | |
477 | if f in seenfiles: |
|
489 | if f in seenfiles: | |
478 | continue |
|
490 | continue | |
479 | seenfiles.add(f) |
|
491 | seenfiles.add(f) | |
480 |
|
492 | |||
481 | i = b'data/%s.i' % f |
|
493 | i = b'data/%s.i' % f | |
482 | d = b'data/%s.d' % f |
|
494 | d = b'data/%s.d' % f | |
483 |
|
495 | |||
484 | if repo.store._exists(i): |
|
496 | if repo.store._exists(i): | |
485 | newentries.add(i) |
|
497 | newentries.add(i) | |
486 | if repo.store._exists(d): |
|
498 | if repo.store._exists(d): | |
487 | newentries.add(d) |
|
499 | newentries.add(d) | |
488 |
|
500 | |||
489 | progress.complete() |
|
501 | progress.complete() | |
490 |
|
502 | |||
491 | if requirements.TREEMANIFEST_REQUIREMENT in repo.requirements: |
|
503 | if requirements.TREEMANIFEST_REQUIREMENT in repo.requirements: | |
492 | # This logic is safe if treemanifest isn't enabled, but also |
|
504 | # This logic is safe if treemanifest isn't enabled, but also |
@@ -316,7 +316,7 b' Show all commands + options' | |||||
316 | debugpushkey: |
|
316 | debugpushkey: | |
317 | debugpvec: |
|
317 | debugpvec: | |
318 | debugrebuilddirstate: rev, minimal |
|
318 | debugrebuilddirstate: rev, minimal | |
319 | debugrebuildfncache: |
|
319 | debugrebuildfncache: only-data | |
320 | debugrename: rev |
|
320 | debugrename: rev | |
321 | debugrequires: |
|
321 | debugrequires: | |
322 | debugrevlog: changelog, manifest, dir, dump |
|
322 | debugrevlog: changelog, manifest, dir, dump |
@@ -86,6 +86,10 b' and the second file.i entry should match' | |||||
86 | warning: revlog 'data/file.d' not in fncache! |
|
86 | warning: revlog 'data/file.d' not in fncache! | |
87 | 1 warnings encountered! |
|
87 | 1 warnings encountered! | |
88 | hint: run "hg debugrebuildfncache" to recover from corrupt fncache |
|
88 | hint: run "hg debugrebuildfncache" to recover from corrupt fncache | |
|
89 | $ hg debugrebuildfncache --only-data | |||
|
90 | adding data/file.d | |||
|
91 | 1 items added, 0 removed from fncache | |||
|
92 | $ hg verify -q | |||
89 | $ cd .. |
|
93 | $ cd .. | |
90 |
|
94 | |||
91 |
|
95 |
General Comments 0
You need to be logged in to leave comments.
Login now