Mercurial > public > mercurial-scm > hg
comparison mercurial/commands.py @ 26024:84c00f03e06c
dirstate: add --minimal flag to debugrebuilddirstate
On repositories with hundreds of thousands of files, hg
debugrebuilddirstate causes every dirstate entry to be marked lookup,
and the next hg status can take many minutes.
This adds a --minimal flag that allows us to only rebuild the parts of the
dirstate that are inconsistent. This follows two rules:
1) If a file is in the dirstate but not in the parent manifest, and it is not
marked 'add', it is busted and we should drop it.
2) If a file is not in the dirstate at all, but it is in the parent
manifest, it should be added to the dirstate and we need to mark it as
lookup.
This allows us to fix repositories where the dirstate doesn't match
the manifest much more quickly.
Tested by artificially adding bad dirstate entries (via code) for both cases
above.
author | Durham Goode <durham@fb.com> |
---|---|
date | Wed, 12 Aug 2015 19:44:21 -0700 |
parents | a0847285d207 |
children | 5243890224ff |
comparison
equal
deleted
inserted
replaced
26023:48671378daeb | 26024:84c00f03e06c |
---|---|
2698 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") % | 2698 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") % |
2699 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec), | 2699 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec), |
2700 pa.distance(pb), rel)) | 2700 pa.distance(pb), rel)) |
2701 | 2701 |
2702 @command('debugrebuilddirstate|debugrebuildstate', | 2702 @command('debugrebuilddirstate|debugrebuildstate', |
2703 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))], | 2703 [('r', 'rev', '', _('revision to rebuild to'), _('REV')), |
2704 ('', 'minimal', None, _('only rebuild files that are inconsistent with ' | |
2705 'the working copy parent')), | |
2706 ], | |
2704 _('[-r REV]')) | 2707 _('[-r REV]')) |
2705 def debugrebuilddirstate(ui, repo, rev): | 2708 def debugrebuilddirstate(ui, repo, rev, **opts): |
2706 """rebuild the dirstate as it would look like for the given revision | 2709 """rebuild the dirstate as it would look like for the given revision |
2707 | 2710 |
2708 If no revision is specified the first current parent will be used. | 2711 If no revision is specified the first current parent will be used. |
2709 | 2712 |
2710 The dirstate will be set to the files of the given revision. | 2713 The dirstate will be set to the files of the given revision. |
2711 The actual working directory content or existing dirstate | 2714 The actual working directory content or existing dirstate |
2712 information such as adds or removes is not considered. | 2715 information such as adds or removes is not considered. |
2716 | |
2717 ``minimal`` will only rebuild the dirstate status for files that claim to be | |
2718 tracked but are not in the parent manifest, or that exist in the parent | |
2719 manifest but are not in the dirstate. It will not change adds, removes, or | |
2720 modified files that are in the working copy parent. | |
2713 | 2721 |
2714 One use of this command is to make the next :hg:`status` invocation | 2722 One use of this command is to make the next :hg:`status` invocation |
2715 check the actual file content. | 2723 check the actual file content. |
2716 """ | 2724 """ |
2717 ctx = scmutil.revsingle(repo, rev) | 2725 ctx = scmutil.revsingle(repo, rev) |
2718 wlock = repo.wlock() | 2726 wlock = repo.wlock() |
2719 try: | 2727 try: |
2720 repo.dirstate.rebuild(ctx.node(), ctx.manifest()) | 2728 dirstate = repo.dirstate |
2729 | |
2730 # See command doc for what minimal does. | |
2731 if opts.get('minimal'): | |
2732 dirstatefiles = set(dirstate) | |
2733 ctxfiles = set(ctx.manifest().keys()) | |
2734 for file in (dirstatefiles | ctxfiles): | |
2735 indirstate = file in dirstatefiles | |
2736 inctx = file in ctxfiles | |
2737 | |
2738 if indirstate and not inctx and dirstate[file] != 'a': | |
2739 dirstate.drop(file) | |
2740 elif inctx and not indirstate: | |
2741 dirstate.normallookup(file) | |
2742 else: | |
2743 dirstate.rebuild(ctx.node(), ctx.manifest()) | |
2721 finally: | 2744 finally: |
2722 wlock.release() | 2745 wlock.release() |
2723 | 2746 |
2724 @command('debugrebuildfncache', [], '') | 2747 @command('debugrebuildfncache', [], '') |
2725 def debugrebuildfncache(ui, repo): | 2748 def debugrebuildfncache(ui, repo): |