Emily Shaffer <emilyshaffer@xxxxxxxxxx> writes: > Teach 'git grep' to use OPT_PATHSPEC_FROM_FILE and update the > documentation accordingly. > > This changes enables 'git grep' to receive the pathspec from a file by > specifying the path, or from stdin by specifying '-' as the path. This > matches the previous functionality of '-f', so the documentation of '-f' > has been expanded to describe this functionality. To let '-f' match the > new '--pathspec-from-file' option, also teach a '--patterns-from-file' > long name to '-f'. > > Since there are now two arguments which can attempt to read from stdin, > add a safeguard to check whether the user specified '-' for both of > them. It is still possible for a user to pass '/dev/stdin' to one or > both arguments at present; we do not explicitly check. OK. I guess this is good enough at least for now and possibly forever as that falls into the "doctor, it hurts when I do this" category. > Refactored to use am/pathspec-from-file. This changes the implementation > significantly since v1, but the testcases mostly remain the same. I am hoping that this topic, and Alexandr's "add" and "checkout" stuff, would help establishing a good pattern for other commands to follow. > diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt > index c89fb569e3..56b1c5a302 100644 > --- a/Documentation/git-grep.txt > +++ b/Documentation/git-grep.txt > @@ -24,7 +24,8 @@ SYNOPSIS > [-A <post-context>] [-B <pre-context>] [-C <context>] > [-W | --function-context] > [--threads <num>] > - [-f <file>] [-e] <pattern> > + [-f | --patterns-from-file <file>] [-e] <pattern> OK. > + [--pathspec-from-file=<file> [--pathspec-file-nul]] OK. > @@ -270,7 +271,10 @@ providing this option will cause it to die. > See `grep.threads` in 'CONFIGURATION' for more information. > > -f <file>:: > - Read patterns from <file>, one per line. > +--patterns-from-file <file>:: > + Read patterns from <file>, one per line. If `<file>` is exactly `-` then > + standard input is used; standard input cannot be used for both > + --patterns-from-file and --pathspec-from-file. Makes sense---otherwise they would compete and we cannot know which kind each line in the standard input is ;-) > @@ -289,6 +293,20 @@ In future versions we may learn to support patterns containing \0 for > more search backends, until then we'll die when the pattern type in > question doesn't support them. > > +--pathspec-from-file <file>:: > + Read pathspec from <file> instead of the command line. If `<file>` is > + exactly `-` then standard input is used; standard input cannot be used > + for both --patterns-from-file and --pathspec-from-file. Pathspec elements > + are separated by LF or CR/LF. Pathspec elements can be quoted as > + explained for the configuration variable `core.quotePath` (see > + linkgit:git-config[1]). See also `--pathspec-file-nul` and global > + `--literal-pathspecs`. > + > +--pathspec-file-nul:: > + Only meaningful with `--pathspec-from-file`. Pathspec elements are > + separated with NUL character and all other characters are taken > + literally (including newlines and quotes). > + I think these matches the ones in git-reset.txt from the earlier work by Alexandr's, which is good. > diff --git a/builtin/grep.c b/builtin/grep.c > index 50ce8d9461..54ba991c42 100644 > --- a/builtin/grep.c > +++ b/builtin/grep.c > @@ -31,6 +31,7 @@ static char const * const grep_usage[] = { > }; > > static int recurse_submodules; > +static int patterns_from_stdin, pathspec_from_stdin; > > #define GREP_NUM_THREADS_DEFAULT 8 > static int num_threads; > @@ -723,15 +724,18 @@ static int context_callback(const struct option *opt, const char *arg, > static int file_callback(const struct option *opt, const char *arg, int unset) > { Shouldn't this be renamed? Earlier, the only thing that can be taken from a file was the patterns, but now a file can be given to specify a set of pathspec elements. "patterns_file_callback()" or something like taht? > struct grep_opt *grep_opt = opt->value; > - int from_stdin; > FILE *patterns; > int lno = 0; > struct strbuf sb = STRBUF_INIT; > > BUG_ON_OPT_NEG(unset); > > - from_stdin = !strcmp(arg, "-"); > - patterns = from_stdin ? stdin : fopen(arg, "r"); > + patterns_from_stdin = !strcmp(arg, "-"); Totally outside the scope of this patch, but we may want to introduce int is_stdin_cmdline_marker(const char *arg) { return !strcmp(arg, "-"); } which later can be taught also about "/dev/stdin". Even outside the pathspec-from-file option, I think "diff --no-index" also has some special-case provision for treating "-" as "input coming from the standard input string", which would benefit from such a helper. > + if (patterns_from_stdin && pathspec_from_stdin) > + die(_("cannot specify both patterns and pathspec via stdin")); It's kind of sad that we need to check this in this callback and also inside cmd_grep() top-level we will see further down... > + if (pathspec_from_file) { > + if (pathspec.nr) > + die(_("--pathspec-from-file is incompatible with pathspec arguments")); > + > + pathspec_from_stdin = !strcmp(pathspec_from_file, "-"); > + > + if (patterns_from_stdin && pathspec_from_stdin) > + die(_("cannot specify both patterns and pathspec via stdin")); ... here. Thanks.