Subject: bug#28105: Inconsistent exit code with --files-without-match

From: Anthony Sottile <[email-masked]>
Date: Wed, 16 Aug 2017 15:04:25 -0700

On Tue, Aug 15, 2017 at 10:15 PM, Paul Eggert <[email-masked]> wrote:
> Anthony Sottile wrote:
>>
>> # Search is for filenames not containing hi, this search is successful
>> **but it exits 1**
>> $ grep -L hi -- f; echo $?
>> f
>> 1
>> # Search is for filenames not containing hello, this search fails
>> **but it exits 0**
>> $ grep -L hello -- f; echo $?
>> 0
>
>
> The grep documentation says exit status depends on whether lines (not files)
> are selected, so grep is conforming to its documentation here. Perhaps
> grep's documentation and behavior could be changed, though I worry that
> existing uses of grep might be adversely affected. What is the use case that
> justifies such a change?

Admittedly, I'm down a rabbit hole at this point but I'll try and
explain the full pathway :)

My initial goal is I am writing a tool to manage multiple git repositories:
- https://github.com/asottile/all-repos

One of the goals of this tool is to be able to grep across all of the
repositories, mapping `git grep` over each repository fits this goal
pretty well.

`all-repos-grep` supports two modes:
- normal mode:
    - for each repository run `git grep $args`
    - if that `git grep` command returns `0`, reproduce the output
with the repository name prefixing each line.
- --repos-with-matches:
    - for each repository run `git grep --quiet $args`
    - if that `git grep` command returns `0`, include this repository
name in the output

While trying some queries, I noticed an oddity (with git grep, not
with gnu grep) in that `git grep -L ...` and `git grep --quiet -L`
were returning different exit codes.

I then reported a bug to the git mailing list about this discrepancy
between return codes when `--quiet` was passed on the cli.  I also
submitted a patch to fix this discrepancy.

It was at this point that a git maintainer noticed that `git grep -L`
and `grep -L` disagreed in exit codes (deferring my patch until the
correct way forward on what `git grep`'s exit codes should be).

The current `git grep -L` exits 1 when no files fit the search (that
is, they *don't* contain the pattern), while `grep -L` exits 0 (the
current `git grep -L` behaviour is the one I'm suggesting for `grep
-L`).

I essentially have two options:
- grep documents / adjust behaviour to be more consistent with "return
0 when successfully finding things", `git grep -L` behaves the same as
today with exit codes.
- adjust my tool to *ignore* exit codes and instead look at output.
This would also mean dropping the `--quiet` optimization.

My main argument is that the inconsistency between grep with/without
`-L` hurts scriptability due to inconsistency.

Anthony