3576 found = False |
3576 found = False |
3577 follow = opts.get(b'follow') |
3577 follow = opts.get(b'follow') |
3578 |
3578 |
3579 getrenamed = scmutil.getrenamedfn(repo) |
3579 getrenamed = scmutil.getrenamedfn(repo) |
3580 |
3580 |
3581 def get_file_content(filename, filelog, filenode, context, revision): |
3581 def readfile(ctx, fn): |
3582 try: |
3582 rev = ctx.rev() |
3583 content = filelog.read(filenode) |
3583 if rev is None: |
3584 except error.WdirUnsupported: |
3584 fctx = ctx[fn] |
3585 content = context[filename].data() |
3585 try: |
3586 except error.CensoredNodeError: |
3586 return fctx.data() |
3587 content = None |
3587 except IOError as e: |
3588 ui.warn( |
3588 if e.errno != errno.ENOENT: |
3589 _(b'cannot search in censored file: %(filename)s:%(revnum)s\n') |
3589 raise |
3590 % {b'filename': filename, b'revnum': pycompat.bytestr(revision)} |
3590 else: |
3591 ) |
3591 flog = getfile(fn) |
3592 return content |
3592 fnode = ctx.filenode(fn) |
|
3593 try: |
|
3594 return flog.read(fnode) |
|
3595 except error.CensoredNodeError: |
|
3596 ui.warn( |
|
3597 _( |
|
3598 b'cannot search in censored file: %(filename)s:%(revnum)s\n' |
|
3599 ) |
|
3600 % {b'filename': fn, b'revnum': pycompat.bytestr(rev),} |
|
3601 ) |
3593 |
3602 |
3594 def prep(ctx, fns): |
3603 def prep(ctx, fns): |
3595 rev = ctx.rev() |
3604 rev = ctx.rev() |
3596 pctx = ctx.p1() |
3605 pctx = ctx.p1() |
3597 matches.setdefault(rev, {}) |
3606 matches.setdefault(rev, {}) |
3598 if diff: |
3607 if diff: |
3599 parent = pctx.rev() |
3608 parent = pctx.rev() |
3600 matches.setdefault(parent, {}) |
3609 matches.setdefault(parent, {}) |
3601 files = revfiles.setdefault(rev, []) |
3610 files = revfiles.setdefault(rev, []) |
3602 for fn in fns: |
3611 for fn in fns: |
3603 flog = getfile(fn) |
3612 # fn might not exist in the revision (could be a file removed by the |
3604 try: |
3613 # revision). We could check `fn not in ctx` even when rev is None, |
3605 fnode = ctx.filenode(fn) |
3614 # but it's less racy to protect againt that in readfile. |
3606 except error.LookupError: |
3615 if rev is not None and fn not in ctx: |
3607 continue |
3616 continue |
3608 |
3617 |
3609 copy = None |
3618 copy = None |
3610 if follow: |
3619 if follow: |
3611 copy = getrenamed(fn, rev) |
3620 copy = getrenamed(fn, rev) |
3616 if fn in skip: |
3625 if fn in skip: |
3617 continue |
3626 continue |
3618 files.append(fn) |
3627 files.append(fn) |
3619 |
3628 |
3620 if fn not in matches[rev]: |
3629 if fn not in matches[rev]: |
3621 content = get_file_content(fn, flog, fnode, ctx, rev) |
3630 grepbody(fn, rev, readfile(ctx, fn)) |
3622 grepbody(fn, rev, content) |
|
3623 |
3631 |
3624 if diff: |
3632 if diff: |
3625 pfn = copy or fn |
3633 pfn = copy or fn |
3626 if pfn not in matches[parent]: |
3634 if pfn not in matches[parent] and pfn in pctx: |
3627 try: |
3635 grepbody(pfn, parent, readfile(pctx, pfn)) |
3628 pfnode = pctx.filenode(pfn) |
|
3629 pcontent = get_file_content( |
|
3630 pfn, flog, pfnode, pctx, parent |
|
3631 ) |
|
3632 grepbody(pfn, parent, pcontent) |
|
3633 except error.LookupError: |
|
3634 pass |
|
3635 |
3636 |
3636 ui.pager(b'grep') |
3637 ui.pager(b'grep') |
3637 fm = ui.formatter(b'grep', opts) |
3638 fm = ui.formatter(b'grep', opts) |
3638 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep): |
3639 for ctx in cmdutil.walkchangerevs(repo, match, opts, prep): |
3639 rev = ctx.rev() |
3640 rev = ctx.rev() |