grep: respect diff attributes for binary-ness
authorJeff King <peff@peff.net>
Thu, 2 Feb 2012 08:21:02 +0000 (03:21 -0500)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Feb 2012 18:36:08 +0000 (10:36 -0800)
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>
grep.c
grep.h
t/t7008-grep-binary.sh

diff --git a/grep.c b/grep.c
index bb1856985b673a3a57cf2aaad8c82d5de2abd521..a50d161721b606f728ffededb43d049f7eb2ce1b 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -1024,11 +1024,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
 
        switch (opt->binary) {
        case GREP_BINARY_DEFAULT:
-               if (buffer_is_binary(gs->buf, gs->size))
+               if (grep_source_is_binary(gs))
                        binary_match_only = 1;
                break;
        case GREP_BINARY_NOMATCH:
-               if (buffer_is_binary(gs->buf, gs->size))
+               if (grep_source_is_binary(gs))
                        return 0; /* Assume unmatch */
                break;
        case GREP_BINARY_TEXT:
@@ -1350,3 +1350,15 @@ void grep_source_load_driver(struct grep_source *gs)
                gs->driver = userdiff_find_by_name("default");
        grep_attr_unlock();
 }
+
+int grep_source_is_binary(struct grep_source *gs)
+{
+       grep_source_load_driver(gs);
+       if (gs->driver->binary != -1)
+               return gs->driver->binary;
+
+       if (!grep_source_load(gs))
+               return buffer_is_binary(gs->buf, gs->size);
+
+       return 0;
+}
diff --git a/grep.h b/grep.h
index 73b28c2df7ca4c9c6e29c759e11a5fb55cfbb7b9..36e49d8255e2952828f367a0e35d4fcb027d9772 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -152,6 +152,7 @@ int grep_source_load(struct grep_source *gs);
 void grep_source_clear_data(struct grep_source *gs);
 void grep_source_clear(struct grep_source *gs);
 void grep_source_load_driver(struct grep_source *gs);
+int grep_source_is_binary(struct grep_source *gs);
 
 int grep_source(struct grep_opt *opt, struct grep_source *gs);
 
index 917a264eea6c6b3593e9f19caadbef715daace20..fd6410fc7149ed381d4d09120089859281e40696 100755 (executable)
@@ -99,4 +99,28 @@ test_expect_success 'git grep y<NUL>x a' "
        test_must_fail git grep -f f a
 "
 
+test_expect_success 'grep respects binary diff attribute' '
+       echo text >t &&
+       git add t &&
+       echo t:text >expect &&
+       git grep text t >actual &&
+       test_cmp expect actual &&
+       echo "t -diff" >.gitattributes &&
+       echo "Binary file t matches" >expect &&
+       git grep text t >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'grep respects not-binary diff attribute' '
+       echo binQary | q_to_nul >b &&
+       git add b &&
+       echo "Binary file b matches" >expect &&
+       git grep bin b >actual &&
+       test_cmp expect actual &&
+       echo "b diff" >.gitattributes &&
+       echo "b:binQary" >expect &&
+       git grep bin b | nul_to_q >actual &&
+       test_cmp expect actual
+'
+
 test_done