[PATCH 1 of 2] repair: add functionality to rebuild fncache
Yuya Nishihara
yuya at tcha.org
Sun Jun 21 01:36:55 CDT 2015
On Sat, 20 Jun 2015 20:21:03 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc at gmail.com>
> # Date 1434856426 25200
> # Sat Jun 20 20:13:46 2015 -0700
> # Node ID 421106879340132e8117e0f0b04409204ccc05da
> # Parent 7fdd1782fc4ee9da87d8af13e806dc9055db2c38
> repair: add functionality to rebuild fncache
>
> Currently, there is no way to recover from a missing or corrupt fncache
> file. This patch changes that.
>
> The `hg debugrebuildfncache` command is introduced. It ensures the
> fncache is up to date by reconstructing the fncache from all seen files
> encountered during a brute force traversal of the repository's entire
> history.
>
> The command will add missing entries and will prune excess ones.
>
> Currently, the command refuses to operate unless the repository has the
> fncache requirement. The command could later grow the ability to
> "upgrade" an existing repository to be fncache enabled.
>
> When testing this patch on a local clone of the Firefox repository, it
> removed a bunch of entries. Investigation revealed that removed entries
> belonged to empty (0 byte size) .i filelogs. I'm not sure how these
> files came into existence. The stripping code does have logic for
> informing the fncache of removed entries. It's possible the behavior was
> or is buggy or some other process that truncates revlogs isn't updating
> fncache accordingly. Whatever the cause, I thought it worth mentioning,
> because it may indicate the implementation of this command is incorrect.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -20,9 +20,9 @@ import merge as mergemod
> import minirst, revset, fileset
> import dagparser, context, simplemerge, graphmod, copies
> import random
> import setdiscovery, treediscovery, dagutil, pvec, localrepo
> -import phases, obsolete, exchange, bundle2
> +import phases, obsolete, exchange, bundle2, repair
> import ui as uimod
>
> table = {}
>
> @@ -2727,8 +2727,13 @@ def debugrebuilddirstate(ui, repo, rev):
> repo.dirstate.rebuild(ctx.node(), ctx.manifest())
> finally:
> wlock.release()
>
> + at command('debugrebuildfncache', [], '')
> +def debugrebuildfncache(ui, repo):
> + """rebuild the fncache file"""
> + repair.rebuildfncache(ui, repo)
> +
> @command('debugrename',
> [('r', 'rev', '', _('revision to debug'), _('REV'))],
> _('[-r REV] FILE'))
> def debugrename(ui, repo, file1, *pats, **opts):
> diff --git a/mercurial/repair.py b/mercurial/repair.py
> --- a/mercurial/repair.py
> +++ b/mercurial/repair.py
> @@ -226,4 +226,69 @@ def strip(ui, repo, nodelist, backup=Tru
> # Remove partial backup only if there were no exceptions
> vfs.unlink(chgrpfile)
>
> repo.destroyed()
> +
> +def rebuildfncache(ui, repo):
> + """Rebuilds the fncache file from repo history.
> +
> + Missing entries will be added. Extra entries will be removed.
> + """
> + if 'fncache' not in repo.requirements:
> + raise util.Abort(_('repository does not support fncache'))
> +
> + lock = repo.lock()
> + try:
> + fnc = repo.store.fncache
> + # Trigger load of fncache.
> + if 'irrelevant' in fnc:
> + pass
> +
> + oldentries = set(fnc.entries)
> + newentries = set()
> + seenfiles = set()
> +
> + repolen = len(repo)
> + for rev in repo:
> + ui.progress(_('changeset'), rev, total=repolen)
> +
> + ctx = repo[rev]
> + for f in ctx.files():
Perhaps it needs unfiltered repo.
More information about the Mercurial-devel
mailing list