diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3440,6 +3440,9 @@ def grep(ui, repo, pattern, *pats, **opt def grepbody(fn, rev, body): matches[rev].setdefault(fn, []) m = matches[rev][fn] + if body is None: + return + for lnum, cstart, cend, line in matchlines(body): s = linestate(line, lnum, cstart, cend) m.append(s) @@ -3575,6 +3578,19 @@ def grep(ui, repo, pattern, *pats, **opt getrenamed = scmutil.getrenamedfn(repo) + def get_file_content(filename, filelog, filenode, context, revision): + try: + content = filelog.read(filenode) + except error.WdirUnsupported: + content = context[filename].data() + except error.CensoredNodeError: + content = None + ui.warn( + _(b'cannot search in censored file: %(filename)s:%(revnum)s\n') + % {b'filename': filename, b'revnum': pycompat.bytestr(revision)} + ) + return content + def prep(ctx, fns): rev = ctx.rev() pctx = ctx.p1() @@ -3601,17 +3617,15 @@ def grep(ui, repo, pattern, *pats, **opt files.append(fn) if fn not in matches[rev]: - try: - content = flog.read(fnode) - except error.WdirUnsupported: - content = ctx[fn].data() + content = get_file_content(fn, flog, fnode, ctx, rev) grepbody(fn, rev, content) pfn = copy or fn if pfn not in matches[parent]: try: - fnode = pctx.filenode(pfn) - grepbody(pfn, parent, flog.read(fnode)) + pfnode = pctx.filenode(pfn) + pcontent = get_file_content(pfn, flog, pfnode, pctx, parent) + grepbody(pfn, parent, pcontent) except error.LookupError: pass diff --git a/tests/test-censor.t b/tests/test-censor.t --- a/tests/test-censor.t +++ b/tests/test-censor.t @@ -442,6 +442,33 @@ Censored nodes can be bundled up and unb checking files checked 14 changesets with 15 changes to 2 files +Grepping only warns, doesn't error out + + $ cd ../rpull + $ hg grep 'Normal file' + bystander:Normal file v2 + $ hg grep nothing + target:Re-sanitized; nothing to see here + $ hg grep --diff 'Normal file' + cannot search in censored file: target:7 + cannot search in censored file: target:10 + cannot search in censored file: target:12 + bystander:6:-:Normal file v2 + cannot search in censored file: target:1 + cannot search in censored file: target:2 + cannot search in censored file: target:3 + bystander:2:-:Normal file here + bystander:2:+:Normal file v2 + bystander:0:+:Normal file here + $ hg grep --diff nothing + cannot search in censored file: target:7 + cannot search in censored file: target:10 + cannot search in censored file: target:12 + target:13:+:Re-sanitized; nothing to see here + cannot search in censored file: target:1 + cannot search in censored file: target:2 + cannot search in censored file: target:3 + Censored nodes can be imported on top of censored nodes, consecutively $ hg init ../rimport