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):