grep: fix coloring of hunk marks between files

Commit 431d6e7b (grep: enable threading for context line printing) split the printing of the "--\n" mark between results from different files out into two places: show_line() in grep.c for the non-threaded case and work_done() in builtin/grep.c for the threaded case. Commit 55f638bd (grep: Colorize filename, line number, and separator) updated the former, but not the latter, so the separators between files are not colored if threads are used. This patch merges the two. In the threaded case, hunk marks are now printed by show_line() for every file, including the first one, and the very first mark is simply skipped in work_done(). This ensures that the output is properly colored and works just as well. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jun 5, 2011 at 17:24 UTC 08303c3636ef750bfafd1c47f363120cb439b367
3 files changed +58 -10
builtin/grep.c
+16 -7
@@ -93,8 +93,7 @@ static pthread_cond_t cond_write;
93 /* Signalled when we are finished with everything. */
94 static pthread_cond_t cond_result;
95
96 -static int print_hunk_marks_between_files;
97 -static int printed_something;
96 +static int skip_first_line;
97
98 static void add_work(enum work_type type, char *name, void *id)
99 {
@@ -160,10 +159,20 @@ static void work_done(struct work_item *w)
159 todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
160 w = &todo[todo_done];
161 if (w->out.len) {
163 - if (print_hunk_marks_between_files && printed_something)
164 - write_or_die(1, "--\n", 3);
165 - write_or_die(1, w->out.buf, w->out.len);
166 - printed_something = 1;
162 + const char *p = w->out.buf;
163 + size_t len = w->out.len;
164 +
165 + /* Skip the leading hunk mark of the first file. */
166 + if (skip_first_line) {
167 + while (len) {
168 + len--;
169 + if (*p++ == '\n')
170 + break;
171 + }
172 + skip_first_line = 0;
173 + }
174 +
175 + write_or_die(1, p, len);
176 }
177 free(w->name);
178 free(w->identifier);
@@ -968,7 +977,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
977
978 if (use_threads) {
979 if (opt.pre_context || opt.post_context)
971 - print_hunk_marks_between_files = 1;
980 + skip_first_line = 1;
981 start_threads(&opt);
982 }
983 #else
grep.c
+12 -3
@@ -941,9 +941,18 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
941 if (!opt->output)
942 opt->output = std_output;
943
944 - if (opt->last_shown && (opt->pre_context || opt->post_context) &&
945 - opt->output == std_output)
946 - opt->show_hunk_mark = 1;
944 + if (opt->pre_context || opt->post_context) {
945 + /* Show hunk marks, except for the first file. */
946 + if (opt->last_shown)
947 + opt->show_hunk_mark = 1;
948 + /*
949 + * If we're using threads then we can't easily identify
950 + * the first file. Always put hunk marks in that case
951 + * and skip the very first one later in work_done().
952 + */
953 + if (opt->output != std_output)
954 + opt->show_hunk_mark = 1;
955 + }
956 opt->last_shown = 0;
957
958 switch (opt->binary) {
t/t7810-grep.sh
+30
@@ -716,4 +716,34 @@ test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
716 test_cmp expected actual
717 '
718
719 +test_config() {
720 + git config "$1" "$2" &&
721 + test_when_finished "git config --unset $1"
722 +}
723 +
724 +cat >expected <<EOF
725 +hello.c<RED>:<RESET>int main(int argc, const char **argv)
726 +hello.c<RED>-<RESET>{
727 +<RED>--<RESET>
728 +hello.c<RED>:<RESET> /* char ?? */
729 +hello.c<RED>-<RESET>}
730 +<RED>--<RESET>
731 +hello_world<RED>:<RESET>Hello_world
732 +hello_world<RED>-<RESET>HeLLo_world
733 +EOF
734 +
735 +test_expect_success 'grep --color, separator' '
736 + test_config color.grep.context normal &&
737 + test_config color.grep.filename normal &&
738 + test_config color.grep.function normal &&
739 + test_config color.grep.linenumber normal &&
740 + test_config color.grep.match normal &&
741 + test_config color.grep.selected normal &&
742 + test_config color.grep.separator red &&
743 +
744 + git grep --color=always -A1 -e char -e lo_w hello.c hello_world |
745 + test_decode_color >actual &&
746 + test_cmp expected actual
747 +'
748 +
749 test_done