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