Re: [PATCH] builtin-grep: workaround for non GNU grep.
- From
Linus Torvalds <torvalds@osdl.org>
- Date
- May 17, 2006, 18:12 UTC
- Message-ID
- <Pine.LNX.4.64.0605171109170.10823@g5.osdl.org>
- In-Reply-To
- <7vhd3ofsyv.fsf@assigned-by-dhcp.cox.net>
On Wed, 17 May 2006, Junio C Hamano wrote:
Show 12 quoted lines
>
> "Bertrand Jacquin" <beber.mailing@gmail.com> writes:
> >
> > #if NO_H_OPTION_IN_GREP
> > push_arg("/dev/null");
> > #else
> > push_arg("-H");
> > push_arg("--");
> > #fi
>
> Exactly because I wanted to avoid conditional compilation using
> C preprocessor directive (#if).I think this is portable and correct.
Of course, it still ignores the fact that not all grep's support some of the flags like -F/-L/-A/-C etc, but for those cases, the external grep itself will happily just say "unrecognized option -F" or similar.
So with this change, "git grep" should handle all the flags the native grep handles, which is really quite fine. We don't _need_ to expose anything more, and if you do want our extensions, you can get them with "--uncached" and an up-to-date index.
No configuration necessary, and we automatically take advantage of any native grep we have, if possible.
Linus
---
diff --git a/builtin-grep.c b/builtin-grep.c index 66111de..d09ddf0 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -453,7 +453,6 @@ static int external_grep(struct grep_opt len = nr = 0; push_arg("grep"); - push_arg("-H"); if (opt->fixed) push_arg("-F"); if (opt->linenum) @@ -503,17 +502,35 @@ static int external_grep(struct grep_opt push_arg("-e"); push_arg(p->pattern); } - push_arg("--"); + + /* + * To make sure we get the header printed out when we want it, + * add /dev/null to the paths to grep. This is unnecessary + * (and wrong) with "-l" or "-L", which always print out the + * name anyway. + * + * GNU grep has "-H", but this is portable. + */ + if (!opt->name_only && !opt->unmatch_name_only) + push_arg("/dev/null"); hit = 0; argc = nr; for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; + const char *name; if (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode))) continue; if (!pathspec_matches(paths, ce->name)) continue; - argv[argc++] = ce->name; + name = ce->name; + if (name[0] == '-') { + int len = ce_namelen(ce); + name = xmalloc(len + 3); + memcpy(name, "./", 2); + memcpy(name + 2, ce->name, len + 1); + } + argv[argc++] = name; if (argc < MAXARGS) continue; hit += exec_grep(argc, argv);