mercurial/commands.py
changeset 45700 c694b1841a5e
parent 45699 888e633f0c1c
child 45719 c10c87c8fe79
equal deleted inserted replaced
45699:888e633f0c1c 45700:c694b1841a5e
    43     grep as grepmod,
    43     grep as grepmod,
    44     hbisect,
    44     hbisect,
    45     help,
    45     help,
    46     hg,
    46     hg,
    47     logcmdutil,
    47     logcmdutil,
    48     match as matchmod,
       
    49     merge as mergemod,
    48     merge as mergemod,
    50     mergestate as mergestatemod,
    49     mergestate as mergestatemod,
    51     narrowspec,
    50     narrowspec,
    52     obsolete,
    51     obsolete,
    53     obsutil,
    52     obsutil,
  3369     Returns 0 if a match is found, 1 otherwise.
  3368     Returns 0 if a match is found, 1 otherwise.
  3370 
  3369 
  3371     """
  3370     """
  3372     opts = pycompat.byteskwargs(opts)
  3371     opts = pycompat.byteskwargs(opts)
  3373     diff = opts.get(b'all') or opts.get(b'diff')
  3372     diff = opts.get(b'all') or opts.get(b'diff')
       
  3373     follow = opts.get(b'follow')
  3374     if diff and opts.get(b'all_files'):
  3374     if diff and opts.get(b'all_files'):
  3375         raise error.Abort(_(b'--diff and --all-files are mutually exclusive'))
  3375         raise error.Abort(_(b'--diff and --all-files are mutually exclusive'))
  3376     if opts.get(b'all_files') is None and not diff:
  3376     if opts.get(b'all_files') is None and not diff:
  3377         opts[b'all_files'] = True
  3377         opts[b'all_files'] = True
  3378     plaingrep = (
  3378     plaingrep = (
  3396         return 1
  3396         return 1
  3397     sep, eol = b':', b'\n'
  3397     sep, eol = b':', b'\n'
  3398     if opts.get(b'print0'):
  3398     if opts.get(b'print0'):
  3399         sep = eol = b'\0'
  3399         sep = eol = b'\0'
  3400 
  3400 
  3401     searcher = grepmod.grepsearcher(ui, repo, regexp)
  3401     searcher = grepmod.grepsearcher(
       
  3402         ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
       
  3403     )
  3402 
  3404 
  3403     getfile = searcher._getfile
  3405     getfile = searcher._getfile
  3404     matches = searcher._matches
  3406     matches = searcher._matches
  3405     copies = searcher._copies
  3407     copies = searcher._copies
  3406 
  3408 
  3513         fm.end()
  3515         fm.end()
  3514 
  3516 
  3515     skip = searcher._skip
  3517     skip = searcher._skip
  3516     revfiles = searcher._revfiles
  3518     revfiles = searcher._revfiles
  3517     found = False
  3519     found = False
  3518     follow = opts.get(b'follow')
       
  3519 
       
  3520     getrenamed = searcher._getrenamed
       
  3521 
       
  3522     def prep(ctx, fmatch):
       
  3523         rev = ctx.rev()
       
  3524         pctx = ctx.p1()
       
  3525         matches.setdefault(rev, {})
       
  3526         if diff:
       
  3527             parent = pctx.rev()
       
  3528             matches.setdefault(parent, {})
       
  3529         files = revfiles.setdefault(rev, [])
       
  3530         if rev is None:
       
  3531             # in `hg grep pattern`, 2/3 of the time is spent is spent in
       
  3532             # pathauditor checks without this in mozilla-central
       
  3533             contextmanager = repo.wvfs.audit.cached
       
  3534         else:
       
  3535             contextmanager = util.nullcontextmanager
       
  3536         with contextmanager():
       
  3537             # TODO: maybe better to warn missing files?
       
  3538             if all_files:
       
  3539                 fmatch = matchmod.badmatch(fmatch, lambda f, msg: None)
       
  3540                 filenames = ctx.matches(fmatch)
       
  3541             else:
       
  3542                 filenames = (f for f in ctx.files() if fmatch(f))
       
  3543             for fn in filenames:
       
  3544                 # fn might not exist in the revision (could be a file removed by
       
  3545                 # the revision). We could check `fn not in ctx` even when rev is
       
  3546                 # None, but it's less racy to protect againt that in readfile.
       
  3547                 if rev is not None and fn not in ctx:
       
  3548                     continue
       
  3549 
       
  3550                 copy = None
       
  3551                 if follow:
       
  3552                     copy = getrenamed(fn, rev)
       
  3553                     if copy:
       
  3554                         copies.setdefault(rev, {})[fn] = copy
       
  3555                         if fn in skip:
       
  3556                             skip.add(copy)
       
  3557                 if fn in skip:
       
  3558                     continue
       
  3559                 files.append(fn)
       
  3560 
       
  3561                 if fn not in matches[rev]:
       
  3562                     searcher._grepbody(fn, rev, searcher._readfile(ctx, fn))
       
  3563 
       
  3564                 if diff:
       
  3565                     pfn = copy or fn
       
  3566                     if pfn not in matches[parent] and pfn in pctx:
       
  3567                         searcher._grepbody(
       
  3568                             pfn, parent, searcher._readfile(pctx, pfn)
       
  3569                         )
       
  3570 
  3520 
  3571     wopts = logcmdutil.walkopts(
  3521     wopts = logcmdutil.walkopts(
  3572         pats=pats,
  3522         pats=pats,
  3573         opts=opts,
  3523         opts=opts,
  3574         revspec=opts[b'rev'],
  3524         revspec=opts[b'rev'],
  3580     )
  3530     )
  3581     revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
  3531     revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
  3582 
  3532 
  3583     ui.pager(b'grep')
  3533     ui.pager(b'grep')
  3584     fm = ui.formatter(b'grep', opts)
  3534     fm = ui.formatter(b'grep', opts)
  3585     for ctx in cmdutil.walkchangerevs(repo, revs, makefilematcher, prep):
  3535     for ctx in cmdutil.walkchangerevs(
       
  3536         repo, revs, makefilematcher, searcher._prep
       
  3537     ):
  3586         rev = ctx.rev()
  3538         rev = ctx.rev()
  3587         parent = ctx.p1().rev()
  3539         parent = ctx.p1().rev()
  3588         for fn in sorted(revfiles.get(rev, [])):
  3540         for fn in sorted(revfiles.get(rev, [])):
  3589             states = matches[rev][fn]
  3541             states = matches[rev][fn]
  3590             copy = copies.get(rev, {}).get(fn)
  3542             copy = copies.get(rev, {}).get(fn)