git grep: Add "-z/--null" option as in GNU's grep.
Here's a trivial patch that adds "-z" and "--null" options to "git grep". It was discussed on the mailing-list that git's "-z" convention should be used instead of GNU grep's "-Z". So things like 'git grep -l -z "$FOO" | xargs -0 sed -i "s/$FOO/$BOO/"' do work now. Signed-off-by: Raphael Zimmerer <killekulla@rdrz.de> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Raphael Zimmerer committed
Oct 1, 2008 at 18:11 UTC
83caecca2f0805d440099d19011fdedc2b3467a5
4 files changed
+26
-3
Documentation/git-grep.txt
+6
@@ -15,6 +15,7 @@ SYNOPSIS
15
[-E | --extended-regexp] [-G | --basic-regexp]
16
[-F | --fixed-strings] [-n]
17
[-l | --files-with-matches] [-L | --files-without-match]
18
+ [-z | --null]
19
[-c | --count] [--all-match]
20
[-A <post-context>] [-B <pre-context>] [-C <context>]
21
[-f <file>] [-e] <pattern>
@@ -94,6 +95,11 @@ OPTIONS
95
For better compatibility with 'git-diff', --name-only is a
96
synonym for --files-with-matches.
97
98
+-z::
99
+--null::
100
+ Output \0 instead of the character that normally follows a
101
+ file name.
102
+
103
-c::
104
--count::
105
Instead of showing every matched line, show the number of
builtin-grep.c
+8
@@ -295,6 +295,9 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
295
push_arg("-l");
296
if (opt->unmatch_name_only)
297
push_arg("-L");
298
+ if (opt->null_following_name)
299
+ /* in GNU grep git's "-z" translates to "-Z" */
300
+ push_arg("-Z");
301
if (opt->count)
302
push_arg("-c");
303
if (opt->post_context || opt->pre_context) {
@@ -599,6 +602,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
602
opt.unmatch_name_only = 1;
603
continue;
604
}
605
+ if (!strcmp("-z", arg) ||
606
+ !strcmp("--null", arg)) {
607
+ opt.null_following_name = 1;
608
+ continue;
609
+ }
610
if (!strcmp("-c", arg) ||
611
!strcmp("--count", arg)) {
612
opt.count = 1;
grep.c
+11
-3
@@ -239,6 +239,8 @@ static int word_char(char ch)
239
static void show_line(struct grep_opt *opt, const char *bol, const char *eol,
240
const char *name, unsigned lno, char sign)
241
{
242
+ if (opt->null_following_name)
243
+ sign = '\0';
244
if (opt->pathname)
245
printf("%s%c", name, sign);
246
if (opt->linenum)
@@ -246,6 +248,11 @@ static void show_line(struct grep_opt *opt, const char *bol, const char *eol,
248
printf("%.*s\n", (int)(eol-bol), bol);
249
}
250
251
+static void show_name(struct grep_opt *opt, const char *name)
252
+{
253
+ printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
254
+}
255
+
256
static int fixmatch(const char *pattern, char *line, regmatch_t *match)
257
{
258
char *hit = strstr(line, pattern);
@@ -489,7 +496,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
496
return 1;
497
}
498
if (opt->name_only) {
492
- printf("%s\n", name);
499
+ show_name(opt, name);
500
return 1;
501
}
502
/* Hit at this line. If we haven't shown the
@@ -555,7 +562,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
562
return 0;
563
if (opt->unmatch_name_only) {
564
/* We did not see any hit, so we want to show this */
558
- printf("%s\n", name);
565
+ show_name(opt, name);
566
return 1;
567
}
568
@@ -565,7 +572,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
572
* make it another option? For now suppress them.
573
*/
574
if (opt->count && count)
568
- printf("%s:%u\n", name, count);
575
+ printf("%s%c%u\n", name,
576
+ opt->null_following_name ? '\0' : ':', count);
577
return !!last_hit;
578
}
579
grep.h
+1
@@ -74,6 +74,7 @@ struct grep_opt {
74
unsigned extended:1;
75
unsigned relative:1;
76
unsigned pathname:1;
77
+ unsigned null_following_name:1;
78
int regflags;
79
unsigned pre_context;
80
unsigned post_context;