aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/grep.c23
-rw-r--r--grep.c15
-rwxr-xr-xt/t7810-grep.sh30
3 files changed, 58 insertions, 10 deletions
diff --git a/builtin/grep.c b/builtin/grep.c
index 871afaa3c..0d5a90b94 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -93,8 +93,7 @@ static pthread_cond_t cond_write;
/* Signalled when we are finished with everything. */
static pthread_cond_t cond_result;
-static int print_hunk_marks_between_files;
-static int printed_something;
+static int skip_first_line;
static void add_work(enum work_type type, char *name, void *id)
{
@@ -160,10 +159,20 @@ static void work_done(struct work_item *w)
todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
w = &todo[todo_done];
if (w->out.len) {
- if (print_hunk_marks_between_files && printed_something)
- write_or_die(1, "--\n", 3);
- write_or_die(1, w->out.buf, w->out.len);
- printed_something = 1;
+ const char *p = w->out.buf;
+ size_t len = w->out.len;
+
+ /* Skip the leading hunk mark of the first file. */
+ if (skip_first_line) {
+ while (len) {
+ len--;
+ if (*p++ == '\n')
+ break;
+ }
+ skip_first_line = 0;
+ }
+
+ write_or_die(1, p, len);
}
free(w->name);
free(w->identifier);
@@ -968,7 +977,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (use_threads) {
if (opt.pre_context || opt.post_context)
- print_hunk_marks_between_files = 1;
+ skip_first_line = 1;
start_threads(&opt);
}
#else
diff --git a/grep.c b/grep.c
index d03d9e24c..3f15085d0 100644
--- a/grep.c
+++ b/grep.c
@@ -941,9 +941,18 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
if (!opt->output)
opt->output = std_output;
- if (opt->last_shown && (opt->pre_context || opt->post_context) &&
- opt->output == std_output)
- opt->show_hunk_mark = 1;
+ if (opt->pre_context || opt->post_context) {
+ /* Show hunk marks, except for the first file. */
+ if (opt->last_shown)
+ opt->show_hunk_mark = 1;
+ /*
+ * If we're using threads then we can't easily identify
+ * the first file. Always put hunk marks in that case
+ * and skip the very first one later in work_done().
+ */
+ if (opt->output != std_output)
+ opt->show_hunk_mark = 1;
+ }
opt->last_shown = 0;
switch (opt->binary) {
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 69bd576d1..539a8fe6e 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -716,4 +716,34 @@ test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '
test_cmp expected actual
'
+test_config() {
+ git config "$1" "$2" &&
+ test_when_finished "git config --unset $1"
+}
+
+cat >expected <<EOF
+hello.c<RED>:<RESET>int main(int argc, const char **argv)
+hello.c<RED>-<RESET>{
+<RED>--<RESET>
+hello.c<RED>:<RESET> /* char ?? */
+hello.c<RED>-<RESET>}
+<RED>--<RESET>
+hello_world<RED>:<RESET>Hello_world
+hello_world<RED>-<RESET>HeLLo_world
+EOF
+
+test_expect_success 'grep --color, separator' '
+ test_config color.grep.context normal &&
+ test_config color.grep.filename normal &&
+ test_config color.grep.function normal &&
+ test_config color.grep.linenumber normal &&
+ test_config color.grep.match normal &&
+ test_config color.grep.selected normal &&
+ test_config color.grep.separator red &&
+
+ git grep --color=always -A1 -e char -e lo_w hello.c hello_world |
+ test_decode_color >actual &&
+ test_cmp expected actual
+'
+
test_done