Skip to content

Commit 08303c3

Browse files
René Scharfegitster
authored andcommitted
grep: fix coloring of hunk marks between files
Commit 431d6e7 (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 55f638b (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>
1 parent a6605d7 commit 08303c3

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

builtin/grep.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ static pthread_cond_t cond_write;
9393
/* Signalled when we are finished with everything. */
9494
static pthread_cond_t cond_result;
9595

96-
static int print_hunk_marks_between_files;
97-
static int printed_something;
96+
static int skip_first_line;
9897

9998
static void add_work(enum work_type type, char *name, void *id)
10099
{
@@ -160,10 +159,20 @@ static void work_done(struct work_item *w)
160159
todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
161160
w = &todo[todo_done];
162161
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);
167176
}
168177
free(w->name);
169178
free(w->identifier);
@@ -968,7 +977,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
968977

969978
if (use_threads) {
970979
if (opt.pre_context || opt.post_context)
971-
print_hunk_marks_between_files = 1;
980+
skip_first_line = 1;
972981
start_threads(&opt);
973982
}
974983
#else

grep.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,18 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
941941
if (!opt->output)
942942
opt->output = std_output;
943943

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+
}
947956
opt->last_shown = 0;
948957

949958
switch (opt->binary) {

t/t7810-grep.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,4 +716,34 @@ test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
716716
test_cmp expected actual
717717
'
718718

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+
719749
test_done

0 commit comments

Comments
 (0)