--- a/mercurial/repair.py Fri Aug 06 16:17:17 2021 -0400
+++ b/mercurial/repair.py Fri Aug 06 16:27:17 2021 -0400
@@ -441,7 +441,7 @@
yield repo.manifestlog.getstorage(dir)
-def rebuildfncache(ui, repo):
+def rebuildfncache(ui, repo, only_data=False):
"""Rebuilds the fncache file from repo history.
Missing entries will be added. Extra entries will be removed.
@@ -465,28 +465,40 @@
newentries = set()
seenfiles = set()
- progress = ui.makeprogress(
- _(b'rebuilding'), unit=_(b'changesets'), total=len(repo)
- )
- for rev in repo:
- progress.update(rev)
+ if only_data:
+ # Trust the listing of .i from the fncache, but not the .d. This is
+ # much faster, because we only need to stat every possible .d files,
+ # instead of reading the full changelog
+ for f in fnc:
+ if f[:5] == b'data/' and f[-2:] == b'.i':
+ seenfiles.add(f[5:-2])
+ newentries.add(f)
+ dataf = f[:-2] + b'.d'
+ if repo.store._exists(dataf):
+ newentries.add(dataf)
+ else:
+ progress = ui.makeprogress(
+ _(b'rebuilding'), unit=_(b'changesets'), total=len(repo)
+ )
+ for rev in repo:
+ progress.update(rev)
- ctx = repo[rev]
- for f in ctx.files():
- # This is to minimize I/O.
- if f in seenfiles:
- continue
- seenfiles.add(f)
+ ctx = repo[rev]
+ for f in ctx.files():
+ # This is to minimize I/O.
+ if f in seenfiles:
+ continue
+ seenfiles.add(f)
- i = b'data/%s.i' % f
- d = b'data/%s.d' % f
+ i = b'data/%s.i' % f
+ d = b'data/%s.d' % f
- if repo.store._exists(i):
- newentries.add(i)
- if repo.store._exists(d):
- newentries.add(d)
+ if repo.store._exists(i):
+ newentries.add(i)
+ if repo.store._exists(d):
+ newentries.add(d)
- progress.complete()
+ progress.complete()
if requirements.TREEMANIFEST_REQUIREMENT in repo.requirements:
# This logic is safe if treemanifest isn't enabled, but also