Code

grep: print context hunk marks between files
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Wed, 1 Jul 2009 22:03:44 +0000 (00:03 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2009 02:16:46 +0000 (19:16 -0700)
Print a hunk mark before matches from a new file are shown, in addition
to the current behaviour of printing them if lines have been skipped.

The result is easier to read, as (presumably unrelated) matches from
different files are separated by a hunk mark.  GNU grep does the same.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-grep.c
grep.c
grep.h
t/t7002-grep.sh

index 73fc922c4995369c0ca86c01200e2a0ea39161ab..48998af9115379f97403e0aeb63ac46f041906eb 100644 (file)
@@ -278,6 +278,17 @@ static int flush_grep(struct grep_opt *opt,
                argc -= 2;
        }
 
+       if (opt->pre_context || opt->post_context) {
+               /*
+                * grep handles hunk marks between files, but we need to
+                * do that ourselves between multiple calls.
+                */
+               if (opt->show_hunk_mark)
+                       write_or_die(1, "--\n", 3);
+               else
+                       opt->show_hunk_mark = 1;
+       }
+
        status = exec_grep(argc, argv);
 
        if (kept_0) {
diff --git a/grep.c b/grep.c
index 6ee80f7fd9b014a0855f9eadb24cb71b9b97836f..4bca759b67e2d386ae87975780b0272209cc2942 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -491,7 +491,12 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
        int rest = eol - bol;
 
        if (opt->pre_context || opt->post_context) {
-               if (opt->last_shown && lno > opt->last_shown + 1)
+               if (opt->last_shown == 0) {
+                       if (opt->show_hunk_mark)
+                               fputs("--\n", stdout);
+                       else
+                               opt->show_hunk_mark = 1;
+               } else if (lno > opt->last_shown + 1)
                        fputs("--\n", stdout);
        }
        opt->last_shown = lno;
diff --git a/grep.h b/grep.h
index 0883214a0935f09ffe4aa8cb1733ce31d342a5d8..730ffd6f531d99787f33ca3fc9b1f49be090ab7f 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -85,6 +85,7 @@ struct grep_opt {
        unsigned pre_context;
        unsigned post_context;
        unsigned last_shown;
+       int show_hunk_mark;
 };
 
 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
index 7868af8f1896e621b98a2ae9b71492a68a96e584..155bfdb7d75c17daae23229d87c7c3e84668f3a4 100755 (executable)
@@ -155,6 +155,28 @@ test_expect_success 'grep -e A --and --not -e B' '
        test_cmp expected actual
 '
 
+cat >expected <<EOF
+y:y yy
+--
+z:zzz
+EOF
+
+# Create 1024 file names that sort between "y" and "z" to make sure
+# the two files are handled by different calls to an external grep.
+# This depends on MAXARGS in builtin-grep.c being 1024 or less.
+c32="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v"
+test_expect_success 'grep -C1, hunk mark between files' '
+       for a in $c32; do for b in $c32; do : >y-$a$b; done; done &&
+       git add y-?? &&
+       git grep -C1 "^[yz]" >actual &&
+       test_cmp expected actual
+'
+
+test_expect_success 'grep -C1 --no-ext-grep, hunk mark between files' '
+       git grep -C1 --no-ext-grep "^[yz]" >actual &&
+       test_cmp expected actual
+'
+
 test_expect_success 'log grep setup' '
        echo a >>file &&
        test_tick &&