Code

grep: --count over binary
[git.git] / grep.c
diff --git a/grep.c b/grep.c
index fdc42062687fa6b8bb77c8d09ed58aee9107692d..35c18b7e28fd8f064f4d7759653c77078a2e5672 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -570,8 +570,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
                        if (opt->show_hunk_mark) {
                                output_color(opt, "--", 2, opt->color_sep);
                                opt->output(opt, "\n", 1);
-                       } else
-                               opt->show_hunk_mark = 1;
+                       }
                } else if (lno > opt->last_shown + 1) {
                        output_color(opt, "--", 2, opt->color_sep);
                        opt->output(opt, "\n", 1);
@@ -772,14 +771,6 @@ int grep_threads_ok(const struct grep_opt *opt)
            !opt->name_only)
                return 0;
 
-       /* If we are showing hunk marks, we should not do it for the
-        * first match. The synchronization problem we get for this
-        * constraint is not yet solved, so we disable threading in
-        * this case.
-        */
-       if (opt->pre_context || opt->post_context)
-               return 0;
-
        return 1;
 }
 
@@ -801,22 +792,27 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
        enum grep_context ctx = GREP_CONTEXT_HEAD;
        xdemitconf_t xecfg;
 
-       opt->last_shown = 0;
-
        if (!opt->output)
                opt->output = std_output;
 
-       if (buffer_is_binary(buf, size)) {
-               switch (opt->binary) {
-               case GREP_BINARY_DEFAULT:
+       if (opt->last_shown && (opt->pre_context || opt->post_context) &&
+           opt->output == std_output)
+               opt->show_hunk_mark = 1;
+       opt->last_shown = 0;
+
+       switch (opt->binary) {
+       case GREP_BINARY_DEFAULT:
+               if (buffer_is_binary(buf, size))
                        binary_match_only = 1;
-                       break;
-               case GREP_BINARY_NOMATCH:
+               break;
+       case GREP_BINARY_NOMATCH:
+               if (buffer_is_binary(buf, size))
                        return 0; /* Assume unmatch */
-                       break;
-               default:
-                       break;
-               }
+               break;
+       case GREP_BINARY_TEXT:
+               break;
+       default:
+               die("bug: unknown binary handling mode");
        }
 
        memset(&xecfg, 0, sizeof(xecfg));
@@ -877,6 +873,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                        count++;
                        if (opt->status_only)
                                return 1;
+                       if (opt->count)
+                               goto next_line;
                        if (binary_match_only) {
                                opt->output(opt, "Binary file ", 12);
                                output_color(opt, name, strlen(name),
@@ -890,16 +888,12 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                        }
                        /* Hit at this line.  If we haven't shown the
                         * pre-context lines, we would need to show them.
-                        * When asked to do "count", this still show
-                        * the context which is nonsense, but the user
-                        * deserves to get that ;-).
                         */
                        if (opt->pre_context)
                                show_pre_context(opt, name, buf, bol, lno);
                        else if (opt->funcname)
                                show_funcname_line(opt, name, buf, bol, lno);
-                       if (!opt->count)
-                               show_line(opt, bol, eol, name, lno, ':');
+                       show_line(opt, bol, eol, name, lno, ':');
                        last_hit = lno;
                }
                else if (last_hit &&
@@ -943,6 +937,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                output_sep(opt, ':');
                snprintf(buf, sizeof(buf), "%u\n", count);
                opt->output(opt, buf, strlen(buf));
+               return 1;
        }
        return !!last_hit;
 }