grep: respect diff attributes for binary-ness

There is currently no way for users to tell git-grep that a particular path is or is not a binary file; instead, grep always relies on its auto-detection (or the user specifying "-a" to treat all binary-looking files like text). This patch teaches git-grep to use the same attribute lookup that is used by git-diff. We could add a new "grep" flag, but that is unnecessarily complex and unlikely to be useful. Despite the name, the "-diff" attribute (or "diff=foo" and the associated diff.foo.binary config option) are really about describing the contents of the path. It's simply historical that diff was the only thing that cared about these attributes in the past. And if this simple approach turns out to be insufficient, we still have a backwards-compatible path forward: we can add a separate "grep" attribute, and fall back to respecting "diff" if it is unset. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Feb 2, 2012 at 03:21 UTC 41b59bfcb16abb738e5c95c95fb462e717d47d4d
3 files changed +39 -2
grep.c
+14 -2
@@ -1024,11 +1024,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
1024
1025 switch (opt->binary) {
1026 case GREP_BINARY_DEFAULT:
1027 - if (buffer_is_binary(gs->buf, gs->size))
1027 + if (grep_source_is_binary(gs))
1028 binary_match_only = 1;
1029 break;
1030 case GREP_BINARY_NOMATCH:
1031 - if (buffer_is_binary(gs->buf, gs->size))
1031 + if (grep_source_is_binary(gs))
1032 return 0; /* Assume unmatch */
1033 break;
1034 case GREP_BINARY_TEXT:
@@ -1350,3 +1350,15 @@ void grep_source_load_driver(struct grep_source *gs)
1350 gs->driver = userdiff_find_by_name("default");
1351 grep_attr_unlock();
1352 }
1353 +
1354 +int grep_source_is_binary(struct grep_source *gs)
1355 +{
1356 + grep_source_load_driver(gs);
1357 + if (gs->driver->binary != -1)
1358 + return gs->driver->binary;
1359 +
1360 + if (!grep_source_load(gs))
1361 + return buffer_is_binary(gs->buf, gs->size);
1362 +
1363 + return 0;
1364 +}
grep.h
+1
@@ -152,6 +152,7 @@ int grep_source_load(struct grep_source *gs);
152 void grep_source_clear_data(struct grep_source *gs);
153 void grep_source_clear(struct grep_source *gs);
154 void grep_source_load_driver(struct grep_source *gs);
155 +int grep_source_is_binary(struct grep_source *gs);
156
157 int grep_source(struct grep_opt *opt, struct grep_source *gs);
158
t/t7008-grep-binary.sh
+24
@@ -99,4 +99,28 @@ test_expect_success 'git grep y<NUL>x a' "
99 test_must_fail git grep -f f a
100 "
101
102 +test_expect_success 'grep respects binary diff attribute' '
103 + echo text >t &&
104 + git add t &&
105 + echo t:text >expect &&
106 + git grep text t >actual &&
107 + test_cmp expect actual &&
108 + echo "t -diff" >.gitattributes &&
109 + echo "Binary file t matches" >expect &&
110 + git grep text t >actual &&
111 + test_cmp expect actual
112 +'
113 +
114 +test_expect_success 'grep respects not-binary diff attribute' '
115 + echo binQary | q_to_nul >b &&
116 + git add b &&
117 + echo "Binary file b matches" >expect &&
118 + git grep bin b >actual &&
119 + test_cmp expect actual &&
120 + echo "b diff" >.gitattributes &&
121 + echo "b:binQary" >expect &&
122 + git grep bin b | nul_to_q >actual &&
123 + test_cmp expect actual
124 +'
125 +
126 test_done