Re: [PATCH] builtin-grep: workaround for non GNU grep.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Wed, 17 May 2006, Junio C Hamano wrote:
>
> "Bertrand Jacquin" <beber.mailing@xxxxxxxxx> 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);
-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]