tests: use 'test_must_be_empty' instead of 'test_cmp <empty> <out>'
[git] / t / t7810-grep.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
5
6 test_description='git grep various.
7 '
8
9 . ./test-lib.sh
10
11 cat >hello.c <<EOF
12 #include <assert.h>
13 #include <stdio.h>
14
15 int main(int argc, const char **argv)
16 {
17         printf("Hello world.\n");
18         return 0;
19         /* char ?? */
20 }
21 EOF
22
23 test_expect_success setup '
24         {
25                 echo foo mmap bar
26                 echo foo_mmap bar
27                 echo foo_mmap bar mmap
28                 echo foo mmap bar_mmap
29                 echo foo_mmap bar mmap baz
30         } >file &&
31         {
32                 echo Hello world
33                 echo HeLLo world
34                 echo Hello_world
35                 echo HeLLo_world
36         } >hello_world &&
37         {
38                 echo "a+b*c"
39                 echo "a+bc"
40                 echo "abc"
41         } >ab &&
42         {
43                 echo d &&
44                 echo 0
45         } >d0 &&
46         echo vvv >v &&
47         echo ww w >w &&
48         echo x x xx x >x &&
49         echo y yy >y &&
50         echo zzz > z &&
51         mkdir t &&
52         echo test >t/t &&
53         echo vvv >t/v &&
54         mkdir t/a &&
55         echo vvv >t/a/v &&
56         {
57                 echo "line without leading space1"
58                 echo " line with leading space1"
59                 echo " line with leading space2"
60                 echo " line with leading space3"
61                 echo "line without leading space2"
62         } >space &&
63         cat >hello.ps1 <<-\EOF &&
64         # No-op.
65         function dummy() {}
66
67         # Say hello.
68         function hello() {
69           echo "Hello world."
70         } # hello
71
72         # Still a no-op.
73         function dummy() {}
74         EOF
75         git add . &&
76         test_tick &&
77         git commit -m initial
78 '
79
80 test_expect_success 'grep should not segfault with a bad input' '
81         test_must_fail git grep "("
82 '
83
84 for H in HEAD ''
85 do
86         case "$H" in
87         HEAD)   HC='HEAD:' L='HEAD' ;;
88         '')     HC= L='in working tree' ;;
89         esac
90
91         test_expect_success "grep -w $L" '
92                 {
93                         echo ${HC}file:1:foo mmap bar
94                         echo ${HC}file:3:foo_mmap bar mmap
95                         echo ${HC}file:4:foo mmap bar_mmap
96                         echo ${HC}file:5:foo_mmap bar mmap baz
97                 } >expected &&
98                 git -c grep.linenumber=false grep -n -w -e mmap $H >actual &&
99                 test_cmp expected actual
100         '
101
102         test_expect_success "grep -w $L (with --column)" '
103                 {
104                         echo ${HC}file:5:foo mmap bar
105                         echo ${HC}file:14:foo_mmap bar mmap
106                         echo ${HC}file:5:foo mmap bar_mmap
107                         echo ${HC}file:14:foo_mmap bar mmap baz
108                 } >expected &&
109                 git grep --column -w -e mmap $H >actual &&
110                 test_cmp expected actual
111         '
112
113         test_expect_success "grep -w $L (with --column, extended OR)" '
114                 {
115                         echo ${HC}file:14:foo_mmap bar mmap
116                         echo ${HC}file:19:foo_mmap bar mmap baz
117                 } >expected &&
118                 git grep --column -w -e mmap$ --or -e baz $H >actual &&
119                 test_cmp expected actual
120         '
121
122         test_expect_success "grep -w $L (with --column, --invert)" '
123                 {
124                         echo ${HC}file:1:foo mmap bar
125                         echo ${HC}file:1:foo_mmap bar
126                         echo ${HC}file:1:foo_mmap bar mmap
127                         echo ${HC}file:1:foo mmap bar_mmap
128                 } >expected &&
129                 git grep --column --invert -w -e baz $H -- file >actual &&
130                 test_cmp expected actual
131         '
132
133         test_expect_success "grep $L (with --column, --invert, extended OR)" '
134                 {
135                         echo ${HC}hello_world:6:HeLLo_world
136                 } >expected &&
137                 git grep --column --invert -e ll --or --not -e _ $H -- hello_world \
138                         >actual &&
139                 test_cmp expected actual
140         '
141
142         test_expect_success "grep $L (with --column, --invert, extended AND)" '
143                 {
144                         echo ${HC}hello_world:3:Hello world
145                         echo ${HC}hello_world:3:Hello_world
146                         echo ${HC}hello_world:6:HeLLo_world
147                 } >expected &&
148                 git grep --column --invert --not -e _ --and --not -e ll $H -- hello_world \
149                         >actual &&
150                 test_cmp expected actual
151         '
152
153         test_expect_success "grep $L (with --column, double-negation)" '
154                 {
155                         echo ${HC}file:1:foo_mmap bar mmap baz
156                 } >expected &&
157                 git grep --column --not \( --not -e foo --or --not -e baz \) $H -- file \
158                         >actual &&
159                 test_cmp expected actual
160         '
161
162         test_expect_success "grep -w $L (with --column, -C)" '
163                 {
164                         echo ${HC}file:5:foo mmap bar
165                         echo ${HC}file-foo_mmap bar
166                         echo ${HC}file:14:foo_mmap bar mmap
167                         echo ${HC}file:5:foo mmap bar_mmap
168                         echo ${HC}file:14:foo_mmap bar mmap baz
169                 } >expected &&
170                 git grep --column -w -C1 -e mmap $H >actual &&
171                 test_cmp expected actual
172         '
173
174         test_expect_success "grep -w $L (with --line-number, --column)" '
175                 {
176                         echo ${HC}file:1:5:foo mmap bar
177                         echo ${HC}file:3:14:foo_mmap bar mmap
178                         echo ${HC}file:4:5:foo mmap bar_mmap
179                         echo ${HC}file:5:14:foo_mmap bar mmap baz
180                 } >expected &&
181                 git grep -n --column -w -e mmap $H >actual &&
182                 test_cmp expected actual
183         '
184
185         test_expect_success "grep -w $L (with non-extended patterns, --column)" '
186                 {
187                         echo ${HC}file:5:foo mmap bar
188                         echo ${HC}file:10:foo_mmap bar
189                         echo ${HC}file:10:foo_mmap bar mmap
190                         echo ${HC}file:5:foo mmap bar_mmap
191                         echo ${HC}file:10:foo_mmap bar mmap baz
192                 } >expected &&
193                 git grep --column -w -e bar -e mmap $H >actual &&
194                 test_cmp expected actual
195         '
196
197         test_expect_success "grep -w $L" '
198                 {
199                         echo ${HC}file:1:foo mmap bar
200                         echo ${HC}file:3:foo_mmap bar mmap
201                         echo ${HC}file:4:foo mmap bar_mmap
202                         echo ${HC}file:5:foo_mmap bar mmap baz
203                 } >expected &&
204                 git -c grep.linenumber=true grep -w -e mmap $H >actual &&
205                 test_cmp expected actual
206         '
207
208         test_expect_success "grep -w $L" '
209                 {
210                         echo ${HC}file:foo mmap bar
211                         echo ${HC}file:foo_mmap bar mmap
212                         echo ${HC}file:foo mmap bar_mmap
213                         echo ${HC}file:foo_mmap bar mmap baz
214                 } >expected &&
215                 git -c grep.linenumber=true grep --no-line-number -w -e mmap $H >actual &&
216                 test_cmp expected actual
217         '
218
219         test_expect_success "grep -w $L (w)" '
220                 test_must_fail git grep -n -w -e "^w" $H >actual &&
221                 test_must_be_empty actual
222         '
223
224         test_expect_success "grep -w $L (x)" '
225                 {
226                         echo ${HC}x:1:x x xx x
227                 } >expected &&
228                 git grep -n -w -e "x xx* x" $H >actual &&
229                 test_cmp expected actual
230         '
231
232         test_expect_success "grep -w $L (y-1)" '
233                 {
234                         echo ${HC}y:1:y yy
235                 } >expected &&
236                 git grep -n -w -e "^y" $H >actual &&
237                 test_cmp expected actual
238         '
239
240         test_expect_success "grep -w $L (y-2)" '
241                 if git grep -n -w -e "^y y" $H >actual
242                 then
243                         echo should not have matched
244                         cat actual
245                         false
246                 else
247                         test_must_be_empty actual
248                 fi
249         '
250
251         test_expect_success "grep -w $L (z)" '
252                 if git grep -n -w -e "^z" $H >actual
253                 then
254                         echo should not have matched
255                         cat actual
256                         false
257                 else
258                         test_must_be_empty actual
259                 fi
260         '
261
262         test_expect_success "grep $L (t-1)" '
263                 echo "${HC}t/t:1:test" >expected &&
264                 git grep -n -e test $H >actual &&
265                 test_cmp expected actual
266         '
267
268         test_expect_success "grep $L (t-2)" '
269                 echo "${HC}t:1:test" >expected &&
270                 (
271                         cd t &&
272                         git grep -n -e test $H
273                 ) >actual &&
274                 test_cmp expected actual
275         '
276
277         test_expect_success "grep $L (t-3)" '
278                 echo "${HC}t/t:1:test" >expected &&
279                 (
280                         cd t &&
281                         git grep --full-name -n -e test $H
282                 ) >actual &&
283                 test_cmp expected actual
284         '
285
286         test_expect_success "grep -c $L (no /dev/null)" '
287                 ! git grep -c test $H | grep /dev/null
288         '
289
290         test_expect_success "grep --max-depth -1 $L" '
291                 {
292                         echo ${HC}t/a/v:1:vvv
293                         echo ${HC}t/v:1:vvv
294                         echo ${HC}v:1:vvv
295                 } >expected &&
296                 git grep --max-depth -1 -n -e vvv $H >actual &&
297                 test_cmp expected actual
298         '
299
300         test_expect_success "grep --max-depth 0 $L" '
301                 {
302                         echo ${HC}v:1:vvv
303                 } >expected &&
304                 git grep --max-depth 0 -n -e vvv $H >actual &&
305                 test_cmp expected actual
306         '
307
308         test_expect_success "grep --max-depth 0 -- '*' $L" '
309                 {
310                         echo ${HC}t/a/v:1:vvv
311                         echo ${HC}t/v:1:vvv
312                         echo ${HC}v:1:vvv
313                 } >expected &&
314                 git grep --max-depth 0 -n -e vvv $H -- "*" >actual &&
315                 test_cmp expected actual
316         '
317
318         test_expect_success "grep --max-depth 1 $L" '
319                 {
320                         echo ${HC}t/v:1:vvv
321                         echo ${HC}v:1:vvv
322                 } >expected &&
323                 git grep --max-depth 1 -n -e vvv $H >actual &&
324                 test_cmp expected actual
325         '
326
327         test_expect_success "grep --max-depth 0 -- t $L" '
328                 {
329                         echo ${HC}t/v:1:vvv
330                 } >expected &&
331                 git grep --max-depth 0 -n -e vvv $H -- t >actual &&
332                 test_cmp expected actual
333         '
334
335         test_expect_success "grep --max-depth 0 -- . t $L" '
336                 {
337                         echo ${HC}t/v:1:vvv
338                         echo ${HC}v:1:vvv
339                 } >expected &&
340                 git grep --max-depth 0 -n -e vvv $H -- . t >actual &&
341                 test_cmp expected actual
342         '
343
344         test_expect_success "grep --max-depth 0 -- t . $L" '
345                 {
346                         echo ${HC}t/v:1:vvv
347                         echo ${HC}v:1:vvv
348                 } >expected &&
349                 git grep --max-depth 0 -n -e vvv $H -- t . >actual &&
350                 test_cmp expected actual
351         '
352         test_expect_success "grep $L with grep.extendedRegexp=false" '
353                 echo "${HC}ab:a+bc" >expected &&
354                 git -c grep.extendedRegexp=false grep "a+b*c" $H ab >actual &&
355                 test_cmp expected actual
356         '
357
358         test_expect_success "grep $L with grep.extendedRegexp=true" '
359                 echo "${HC}ab:abc" >expected &&
360                 git -c grep.extendedRegexp=true grep "a+b*c" $H ab >actual &&
361                 test_cmp expected actual
362         '
363
364         test_expect_success "grep $L with grep.patterntype=basic" '
365                 echo "${HC}ab:a+bc" >expected &&
366                 git -c grep.patterntype=basic grep "a+b*c" $H ab >actual &&
367                 test_cmp expected actual
368         '
369
370         test_expect_success "grep $L with grep.patterntype=extended" '
371                 echo "${HC}ab:abc" >expected &&
372                 git -c grep.patterntype=extended grep "a+b*c" $H ab >actual &&
373                 test_cmp expected actual
374         '
375
376         test_expect_success "grep $L with grep.patterntype=fixed" '
377                 echo "${HC}ab:a+b*c" >expected &&
378                 git -c grep.patterntype=fixed grep "a+b*c" $H ab >actual &&
379                 test_cmp expected actual
380         '
381
382         test_expect_success PCRE "grep $L with grep.patterntype=perl" '
383                 echo "${HC}ab:a+b*c" >expected &&
384                 git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" $H ab >actual &&
385                 test_cmp expected actual
386         '
387
388         test_expect_success !PCRE "grep $L with grep.patterntype=perl errors without PCRE" '
389                 test_must_fail git -c grep.patterntype=perl grep "foo.*bar"
390         '
391
392         test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
393                 echo "${HC}ab:abc" >expected &&
394                 git \
395                         -c grep.patternType=default \
396                         -c grep.extendedRegexp=true \
397                         grep "a+b*c" $H ab >actual &&
398                 test_cmp expected actual
399         '
400
401         test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
402                 echo "${HC}ab:abc" >expected &&
403                 git \
404                         -c grep.extendedRegexp=true \
405                         -c grep.patternType=default \
406                         grep "a+b*c" $H ab >actual &&
407                 test_cmp expected actual
408         '
409
410         test_expect_success "grep $L with grep.patternType=extended and grep.extendedRegexp=false" '
411                 echo "${HC}ab:abc" >expected &&
412                 git \
413                         -c grep.patternType=extended \
414                         -c grep.extendedRegexp=false \
415                         grep "a+b*c" $H ab >actual &&
416                 test_cmp expected actual
417         '
418
419         test_expect_success "grep $L with grep.patternType=basic and grep.extendedRegexp=true" '
420                 echo "${HC}ab:a+bc" >expected &&
421                 git \
422                         -c grep.patternType=basic \
423                         -c grep.extendedRegexp=true \
424                         grep "a+b*c" $H ab >actual &&
425                 test_cmp expected actual
426         '
427
428         test_expect_success "grep $L with grep.extendedRegexp=false and grep.patternType=extended" '
429                 echo "${HC}ab:abc" >expected &&
430                 git \
431                         -c grep.extendedRegexp=false \
432                         -c grep.patternType=extended \
433                         grep "a+b*c" $H ab >actual &&
434                 test_cmp expected actual
435         '
436
437         test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=basic" '
438                 echo "${HC}ab:a+bc" >expected &&
439                 git \
440                         -c grep.extendedRegexp=true \
441                         -c grep.patternType=basic \
442                         grep "a+b*c" $H ab >actual &&
443                 test_cmp expected actual
444         '
445
446         test_expect_success "grep --count $L" '
447                 echo ${HC}ab:3 >expected &&
448                 git grep --count -e b $H -- ab >actual &&
449                 test_cmp expected actual
450         '
451
452         test_expect_success "grep --count -h $L" '
453                 echo 3 >expected &&
454                 git grep --count -h -e b $H -- ab >actual &&
455                 test_cmp expected actual
456         '
457 done
458
459 cat >expected <<EOF
460 file
461 EOF
462 test_expect_success 'grep -l -C' '
463         git grep -l -C1 foo >actual &&
464         test_cmp expected actual
465 '
466
467 cat >expected <<EOF
468 file:5
469 EOF
470 test_expect_success 'grep -c -C' '
471         git grep -c -C1 foo >actual &&
472         test_cmp expected actual
473 '
474
475 test_expect_success 'grep -L -C' '
476         git ls-files >expected &&
477         git grep -L -C1 nonexistent_string >actual &&
478         test_cmp expected actual
479 '
480
481 test_expect_success 'grep --files-without-match --quiet' '
482         git grep --files-without-match --quiet nonexistent_string >actual &&
483         test_must_be_empty actual
484 '
485
486 cat >expected <<EOF
487 file:foo mmap bar_mmap
488 EOF
489
490 test_expect_success 'grep -e A --and -e B' '
491         git grep -e "foo mmap" --and -e bar_mmap >actual &&
492         test_cmp expected actual
493 '
494
495 cat >expected <<EOF
496 file:foo_mmap bar mmap
497 file:foo_mmap bar mmap baz
498 EOF
499
500
501 test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
502         git grep \( -e foo_ --or -e baz \) \
503                 --and -e " mmap" >actual &&
504         test_cmp expected actual
505 '
506
507 cat >expected <<EOF
508 file:foo mmap bar
509 EOF
510
511 test_expect_success 'grep -e A --and --not -e B' '
512         git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
513         test_cmp expected actual
514 '
515
516 test_expect_success 'grep should ignore GREP_OPTIONS' '
517         GREP_OPTIONS=-v git grep " mmap bar\$" >actual &&
518         test_cmp expected actual
519 '
520
521 test_expect_success 'grep -f, non-existent file' '
522         test_must_fail git grep -f patterns
523 '
524
525 cat >expected <<EOF
526 file:foo mmap bar
527 file:foo_mmap bar
528 file:foo_mmap bar mmap
529 file:foo mmap bar_mmap
530 file:foo_mmap bar mmap baz
531 EOF
532
533 cat >pattern <<EOF
534 mmap
535 EOF
536
537 test_expect_success 'grep -f, one pattern' '
538         git grep -f pattern >actual &&
539         test_cmp expected actual
540 '
541
542 cat >expected <<EOF
543 file:foo mmap bar
544 file:foo_mmap bar
545 file:foo_mmap bar mmap
546 file:foo mmap bar_mmap
547 file:foo_mmap bar mmap baz
548 t/a/v:vvv
549 t/v:vvv
550 v:vvv
551 EOF
552
553 cat >patterns <<EOF
554 mmap
555 vvv
556 EOF
557
558 test_expect_success 'grep -f, multiple patterns' '
559         git grep -f patterns >actual &&
560         test_cmp expected actual
561 '
562
563 test_expect_success 'grep, multiple patterns' '
564         git grep "$(cat patterns)" >actual &&
565         test_cmp expected actual
566 '
567
568 cat >expected <<EOF
569 file:foo mmap bar
570 file:foo_mmap bar
571 file:foo_mmap bar mmap
572 file:foo mmap bar_mmap
573 file:foo_mmap bar mmap baz
574 t/a/v:vvv
575 t/v:vvv
576 v:vvv
577 EOF
578
579 cat >patterns <<EOF
580
581 mmap
582
583 vvv
584
585 EOF
586
587 test_expect_success 'grep -f, ignore empty lines' '
588         git grep -f patterns >actual &&
589         test_cmp expected actual
590 '
591
592 test_expect_success 'grep -f, ignore empty lines, read patterns from stdin' '
593         git grep -f - <patterns >actual &&
594         test_cmp expected actual
595 '
596
597 cat >expected <<EOF
598 y:y yy
599 --
600 z:zzz
601 EOF
602
603 test_expect_success 'grep -q, silently report matches' '
604         git grep -q mmap >actual &&
605         test_must_be_empty actual &&
606         test_must_fail git grep -q qfwfq >actual &&
607         test_must_be_empty actual
608 '
609
610 test_expect_success 'grep -C1 hunk mark between files' '
611         git grep -C1 "^[yz]" >actual &&
612         test_cmp expected actual
613 '
614
615 test_expect_success 'log grep setup' '
616         echo a >>file &&
617         test_tick &&
618         GIT_AUTHOR_NAME="With * Asterisk" \
619         GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \
620         git commit -a -m "second" &&
621
622         echo a >>file &&
623         test_tick &&
624         git commit -a -m "third" &&
625
626         echo a >>file &&
627         test_tick &&
628         GIT_AUTHOR_NAME="Night Fall" \
629         GIT_AUTHOR_EMAIL="nitfol@frobozz.com" \
630         git commit -a -m "fourth"
631 '
632
633 test_expect_success 'log grep (1)' '
634         git log --author=author --pretty=tformat:%s >actual &&
635         {
636                 echo third && echo initial
637         } >expect &&
638         test_cmp expect actual
639 '
640
641 test_expect_success 'log grep (2)' '
642         git log --author=" * " -F --pretty=tformat:%s >actual &&
643         {
644                 echo second
645         } >expect &&
646         test_cmp expect actual
647 '
648
649 test_expect_success 'log grep (3)' '
650         git log --author="^A U" --pretty=tformat:%s >actual &&
651         {
652                 echo third && echo initial
653         } >expect &&
654         test_cmp expect actual
655 '
656
657 test_expect_success 'log grep (4)' '
658         git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
659         {
660                 echo second
661         } >expect &&
662         test_cmp expect actual
663 '
664
665 test_expect_success 'log grep (5)' '
666         git log --author=Thor -F --pretty=tformat:%s >actual &&
667         {
668                 echo third && echo initial
669         } >expect &&
670         test_cmp expect actual
671 '
672
673 test_expect_success 'log grep (6)' '
674         git log --author=-0700  --pretty=tformat:%s >actual &&
675         test_must_be_empty actual
676 '
677
678 test_expect_success 'log grep (7)' '
679         git log -g --grep-reflog="commit: third" --pretty=tformat:%s >actual &&
680         echo third >expect &&
681         test_cmp expect actual
682 '
683
684 test_expect_success 'log grep (8)' '
685         git log -g --grep-reflog="commit: third" --grep-reflog="commit: second" --pretty=tformat:%s >actual &&
686         {
687                 echo third && echo second
688         } >expect &&
689         test_cmp expect actual
690 '
691
692 test_expect_success 'log grep (9)' '
693         git log -g --grep-reflog="commit: third" --author="Thor" --pretty=tformat:%s >actual &&
694         echo third >expect &&
695         test_cmp expect actual
696 '
697
698 test_expect_success 'log grep (9)' '
699         git log -g --grep-reflog="commit: third" --author="non-existent" --pretty=tformat:%s >actual &&
700         test_must_be_empty actual
701 '
702
703 test_expect_success 'log --grep-reflog can only be used under -g' '
704         test_must_fail git log --grep-reflog="commit: third"
705 '
706
707 test_expect_success 'log with multiple --grep uses union' '
708         git log --grep=i --grep=r --format=%s >actual &&
709         {
710                 echo fourth && echo third && echo initial
711         } >expect &&
712         test_cmp expect actual
713 '
714
715 test_expect_success 'log --all-match with multiple --grep uses intersection' '
716         git log --all-match --grep=i --grep=r --format=%s >actual &&
717         {
718                 echo third
719         } >expect &&
720         test_cmp expect actual
721 '
722
723 test_expect_success 'log with multiple --author uses union' '
724         git log --author="Thor" --author="Aster" --format=%s >actual &&
725         {
726             echo third && echo second && echo initial
727         } >expect &&
728         test_cmp expect actual
729 '
730
731 test_expect_success 'log --all-match with multiple --author still uses union' '
732         git log --all-match --author="Thor" --author="Aster" --format=%s >actual &&
733         {
734             echo third && echo second && echo initial
735         } >expect &&
736         test_cmp expect actual
737 '
738
739 test_expect_success 'log --grep --author uses intersection' '
740         # grep matches only third and fourth
741         # author matches only initial and third
742         git log --author="A U Thor" --grep=r --format=%s >actual &&
743         {
744                 echo third
745         } >expect &&
746         test_cmp expect actual
747 '
748
749 test_expect_success 'log --grep --grep --author takes union of greps and intersects with author' '
750         # grep matches initial and second but not third
751         # author matches only initial and third
752         git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
753         {
754                 echo initial
755         } >expect &&
756         test_cmp expect actual
757 '
758
759 test_expect_success 'log ---all-match -grep --author --author still takes union of authors and intersects with grep' '
760         # grep matches only initial and third
761         # author matches all but second
762         git log --all-match --author="Thor" --author="Night" --grep=i --format=%s >actual &&
763         {
764             echo third && echo initial
765         } >expect &&
766         test_cmp expect actual
767 '
768
769 test_expect_success 'log --grep --author --author takes union of authors and intersects with grep' '
770         # grep matches only initial and third
771         # author matches all but second
772         git log --author="Thor" --author="Night" --grep=i --format=%s >actual &&
773         {
774             echo third && echo initial
775         } >expect &&
776         test_cmp expect actual
777 '
778
779 test_expect_success 'log --all-match --grep --grep --author takes intersection' '
780         # grep matches only third
781         # author matches only initial and third
782         git log --all-match --author="A U Thor" --grep=i --grep=r --format=%s >actual &&
783         {
784                 echo third
785         } >expect &&
786         test_cmp expect actual
787 '
788
789 test_expect_success 'log --author does not search in timestamp' '
790         git log --author="$GIT_AUTHOR_DATE" >actual &&
791         test_must_be_empty actual
792 '
793
794 test_expect_success 'log --committer does not search in timestamp' '
795         git log --committer="$GIT_COMMITTER_DATE" >actual &&
796         test_must_be_empty actual
797 '
798
799 test_expect_success 'grep with CE_VALID file' '
800         git update-index --assume-unchanged t/t &&
801         rm t/t &&
802         test "$(git grep test)" = "t/t:test" &&
803         git update-index --no-assume-unchanged t/t &&
804         git checkout t/t
805 '
806
807 cat >expected <<EOF
808 hello.c=#include <stdio.h>
809 hello.c:        return 0;
810 EOF
811
812 test_expect_success 'grep -p with userdiff' '
813         git config diff.custom.funcname "^#" &&
814         echo "hello.c diff=custom" >.gitattributes &&
815         git grep -p return >actual &&
816         test_cmp expected actual
817 '
818
819 cat >expected <<EOF
820 hello.c=int main(int argc, const char **argv)
821 hello.c:        return 0;
822 EOF
823
824 test_expect_success 'grep -p' '
825         rm -f .gitattributes &&
826         git grep -p return >actual &&
827         test_cmp expected actual
828 '
829
830 cat >expected <<EOF
831 hello.c-#include <stdio.h>
832 hello.c-
833 hello.c=int main(int argc, const char **argv)
834 hello.c-{
835 hello.c-        printf("Hello world.\n");
836 hello.c:        return 0;
837 EOF
838
839 test_expect_success 'grep -p -B5' '
840         git grep -p -B5 return >actual &&
841         test_cmp expected actual
842 '
843
844 cat >expected <<EOF
845 hello.c=int main(int argc, const char **argv)
846 hello.c-{
847 hello.c-        printf("Hello world.\n");
848 hello.c:        return 0;
849 hello.c-        /* char ?? */
850 hello.c-}
851 EOF
852
853 test_expect_success 'grep -W' '
854         git grep -W return >actual &&
855         test_cmp expected actual
856 '
857
858 cat >expected <<EOF
859 hello.c-#include <assert.h>
860 hello.c:#include <stdio.h>
861 EOF
862
863 test_expect_success 'grep -W shows no trailing empty lines' '
864         git grep -W stdio >actual &&
865         test_cmp expected actual
866 '
867
868 test_expect_success 'grep -W with userdiff' '
869         test_when_finished "rm -f .gitattributes" &&
870         git config diff.custom.xfuncname "^function .*$" &&
871         echo "hello.ps1 diff=custom" >.gitattributes &&
872         git grep -W echo >function-context-userdiff-actual
873 '
874
875 test_expect_success ' includes preceding comment' '
876         grep "# Say hello" function-context-userdiff-actual
877 '
878
879 test_expect_success ' includes function line' '
880         grep "=function hello" function-context-userdiff-actual
881 '
882
883 test_expect_success ' includes matching line' '
884         grep ":  echo" function-context-userdiff-actual
885 '
886
887 test_expect_success ' includes last line of the function' '
888         grep "} # hello" function-context-userdiff-actual
889 '
890
891 for threads in $(test_seq 0 10)
892 do
893         test_expect_success "grep --threads=$threads & -c grep.threads=$threads" "
894                 git grep --threads=$threads . >actual.$threads &&
895                 if test $threads -ge 1
896                 then
897                         test_cmp actual.\$(($threads - 1)) actual.$threads
898                 fi &&
899                 git -c grep.threads=$threads grep . >actual.$threads &&
900                 if test $threads -ge 1
901                 then
902                         test_cmp actual.\$(($threads - 1)) actual.$threads
903                 fi
904         "
905 done
906
907 test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'grep --threads=N or pack.threads=N warns when no pthreads' '
908         git grep --threads=2 Hello hello_world 2>err &&
909         grep ^warning: err >warnings &&
910         test_line_count = 1 warnings &&
911         grep -F "no threads support, ignoring --threads" err &&
912         git -c grep.threads=2 grep Hello hello_world 2>err &&
913         grep ^warning: err >warnings &&
914         test_line_count = 1 warnings &&
915         grep -F "no threads support, ignoring grep.threads" err &&
916         git -c grep.threads=2 grep --threads=4 Hello hello_world 2>err &&
917         grep ^warning: err >warnings &&
918         test_line_count = 2 warnings &&
919         grep -F "no threads support, ignoring --threads" err &&
920         grep -F "no threads support, ignoring grep.threads" err &&
921         git -c grep.threads=0 grep --threads=0 Hello hello_world 2>err &&
922         test_line_count = 0 err
923 '
924
925 test_expect_success 'grep from a subdirectory to search wider area (1)' '
926         mkdir -p s &&
927         (
928                 cd s && git grep "x x x" ..
929         )
930 '
931
932 test_expect_success 'grep from a subdirectory to search wider area (2)' '
933         mkdir -p s &&
934         (
935                 cd s || exit 1
936                 ( git grep xxyyzz .. >out ; echo $? >status )
937                 test_must_be_empty out &&
938                 test 1 = $(cat status)
939         )
940 '
941
942 cat >expected <<EOF
943 hello.c:int main(int argc, const char **argv)
944 EOF
945
946 test_expect_success 'grep -Fi' '
947         git grep -Fi "CHAR *" >actual &&
948         test_cmp expected actual
949 '
950
951 test_expect_success 'outside of git repository' '
952         rm -fr non &&
953         mkdir -p non/git/sub &&
954         echo hello >non/git/file1 &&
955         echo world >non/git/sub/file2 &&
956         {
957                 echo file1:hello &&
958                 echo sub/file2:world
959         } >non/expect.full &&
960         echo file2:world >non/expect.sub &&
961         (
962                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
963                 export GIT_CEILING_DIRECTORIES &&
964                 cd non/git &&
965                 test_must_fail git grep o &&
966                 git grep --no-index o >../actual.full &&
967                 test_cmp ../expect.full ../actual.full &&
968                 cd sub &&
969                 test_must_fail git grep o &&
970                 git grep --no-index o >../../actual.sub &&
971                 test_cmp ../../expect.sub ../../actual.sub
972         ) &&
973
974         echo ".*o*" >non/git/.gitignore &&
975         (
976                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
977                 export GIT_CEILING_DIRECTORIES &&
978                 cd non/git &&
979                 test_must_fail git grep o &&
980                 git grep --no-index --exclude-standard o >../actual.full &&
981                 test_cmp ../expect.full ../actual.full &&
982
983                 {
984                         echo ".gitignore:.*o*" &&
985                         cat ../expect.full
986                 } >../expect.with.ignored &&
987                 git grep --no-index --no-exclude o >../actual.full &&
988                 test_cmp ../expect.with.ignored ../actual.full
989         )
990 '
991
992 test_expect_success 'outside of git repository with fallbackToNoIndex' '
993         rm -fr non &&
994         mkdir -p non/git/sub &&
995         echo hello >non/git/file1 &&
996         echo world >non/git/sub/file2 &&
997         cat <<-\EOF >non/expect.full &&
998         file1:hello
999         sub/file2:world
1000         EOF
1001         echo file2:world >non/expect.sub &&
1002         (
1003                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1004                 export GIT_CEILING_DIRECTORIES &&
1005                 cd non/git &&
1006                 test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1007                 git -c grep.fallbackToNoIndex=true grep o >../actual.full &&
1008                 test_cmp ../expect.full ../actual.full &&
1009                 cd sub &&
1010                 test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1011                 git -c grep.fallbackToNoIndex=true grep o >../../actual.sub &&
1012                 test_cmp ../../expect.sub ../../actual.sub
1013         ) &&
1014
1015         echo ".*o*" >non/git/.gitignore &&
1016         (
1017                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1018                 export GIT_CEILING_DIRECTORIES &&
1019                 cd non/git &&
1020                 test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1021                 git -c grep.fallbackToNoIndex=true grep --exclude-standard o >../actual.full &&
1022                 test_cmp ../expect.full ../actual.full &&
1023
1024                 {
1025                         echo ".gitignore:.*o*" &&
1026                         cat ../expect.full
1027                 } >../expect.with.ignored &&
1028                 git -c grep.fallbackToNoIndex grep --no-exclude o >../actual.full &&
1029                 test_cmp ../expect.with.ignored ../actual.full
1030         )
1031 '
1032
1033 test_expect_success 'inside git repository but with --no-index' '
1034         rm -fr is &&
1035         mkdir -p is/git/sub &&
1036         echo hello >is/git/file1 &&
1037         echo world >is/git/sub/file2 &&
1038         echo ".*o*" >is/git/.gitignore &&
1039         {
1040                 echo file1:hello &&
1041                 echo sub/file2:world
1042         } >is/expect.unignored &&
1043         {
1044                 echo ".gitignore:.*o*" &&
1045                 cat is/expect.unignored
1046         } >is/expect.full &&
1047         echo file2:world >is/expect.sub &&
1048         (
1049                 cd is/git &&
1050                 git init &&
1051                 test_must_fail git grep o >../actual.full &&
1052                 test_must_be_empty ../actual.full &&
1053
1054                 git grep --untracked o >../actual.unignored &&
1055                 test_cmp ../expect.unignored ../actual.unignored &&
1056
1057                 git grep --no-index o >../actual.full &&
1058                 test_cmp ../expect.full ../actual.full &&
1059
1060                 git grep --no-index --exclude-standard o >../actual.unignored &&
1061                 test_cmp ../expect.unignored ../actual.unignored &&
1062
1063                 cd sub &&
1064                 test_must_fail git grep o >../../actual.sub &&
1065                 test_must_be_empty ../../actual.sub &&
1066
1067                 git grep --no-index o >../../actual.sub &&
1068                 test_cmp ../../expect.sub ../../actual.sub &&
1069
1070                 git grep --untracked o >../../actual.sub &&
1071                 test_cmp ../../expect.sub ../../actual.sub
1072         )
1073 '
1074
1075 test_expect_success 'grep --no-index descends into repos, but not .git' '
1076         rm -fr non &&
1077         mkdir -p non/git &&
1078         (
1079                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1080                 export GIT_CEILING_DIRECTORIES &&
1081                 cd non/git &&
1082
1083                 echo magic >file &&
1084                 git init repo &&
1085                 (
1086                         cd repo &&
1087                         echo magic >file &&
1088                         git add file &&
1089                         git commit -m foo &&
1090                         echo magic >.git/file
1091                 ) &&
1092
1093                 cat >expect <<-\EOF &&
1094                 file
1095                 repo/file
1096                 EOF
1097                 git grep -l --no-index magic >actual &&
1098                 test_cmp expect actual
1099         )
1100 '
1101
1102 test_expect_success 'setup double-dash tests' '
1103 cat >double-dash <<EOF &&
1104 --
1105 ->
1106 other
1107 EOF
1108 git add double-dash
1109 '
1110
1111 cat >expected <<EOF
1112 double-dash:->
1113 EOF
1114 test_expect_success 'grep -- pattern' '
1115         git grep -- "->" >actual &&
1116         test_cmp expected actual
1117 '
1118 test_expect_success 'grep -- pattern -- pathspec' '
1119         git grep -- "->" -- double-dash >actual &&
1120         test_cmp expected actual
1121 '
1122 test_expect_success 'grep -e pattern -- path' '
1123         git grep -e "->" -- double-dash >actual &&
1124         test_cmp expected actual
1125 '
1126
1127 cat >expected <<EOF
1128 double-dash:--
1129 EOF
1130 test_expect_success 'grep -e -- -- path' '
1131         git grep -e -- -- double-dash >actual &&
1132         test_cmp expected actual
1133 '
1134
1135 test_expect_success 'dashdash disambiguates rev as rev' '
1136         test_when_finished "rm -f master" &&
1137         echo content >master &&
1138         echo master:hello.c >expect &&
1139         git grep -l o master -- hello.c >actual &&
1140         test_cmp expect actual
1141 '
1142
1143 test_expect_success 'dashdash disambiguates pathspec as pathspec' '
1144         test_when_finished "git rm -f master" &&
1145         echo content >master &&
1146         git add master &&
1147         echo master:content >expect &&
1148         git grep o -- master >actual &&
1149         test_cmp expect actual
1150 '
1151
1152 test_expect_success 'report bogus arg without dashdash' '
1153         test_must_fail git grep o does-not-exist
1154 '
1155
1156 test_expect_success 'report bogus rev with dashdash' '
1157         test_must_fail git grep o hello.c --
1158 '
1159
1160 test_expect_success 'allow non-existent path with dashdash' '
1161         # We need a real match so grep exits with success.
1162         tree=$(git ls-tree HEAD |
1163                sed s/hello.c/not-in-working-tree/ |
1164                git mktree) &&
1165         git grep o "$tree" -- not-in-working-tree
1166 '
1167
1168 test_expect_success 'grep --no-index pattern -- path' '
1169         rm -fr non &&
1170         mkdir -p non/git &&
1171         (
1172                 GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1173                 export GIT_CEILING_DIRECTORIES &&
1174                 cd non/git &&
1175                 echo hello >hello &&
1176                 echo goodbye >goodbye &&
1177                 echo hello:hello >expect &&
1178                 git grep --no-index o -- hello >actual &&
1179                 test_cmp expect actual
1180         )
1181 '
1182
1183 test_expect_success 'grep --no-index complains of revs' '
1184         test_must_fail git grep --no-index o master -- 2>err &&
1185         test_i18ngrep "cannot be used with revs" err
1186 '
1187
1188 test_expect_success 'grep --no-index prefers paths to revs' '
1189         test_when_finished "rm -f master" &&
1190         echo content >master &&
1191         echo master:content >expect &&
1192         git grep --no-index o master >actual &&
1193         test_cmp expect actual
1194 '
1195
1196 test_expect_success 'grep --no-index does not "diagnose" revs' '
1197         test_must_fail git grep --no-index o :1:hello.c 2>err &&
1198         test_i18ngrep ! -i "did you mean" err
1199 '
1200
1201 cat >expected <<EOF
1202 hello.c:int main(int argc, const char **argv)
1203 hello.c:        printf("Hello world.\n");
1204 EOF
1205
1206 test_expect_success PCRE 'grep --perl-regexp pattern' '
1207         git grep --perl-regexp "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1208         test_cmp expected actual
1209 '
1210
1211 test_expect_success !PCRE 'grep --perl-regexp pattern errors without PCRE' '
1212         test_must_fail git grep --perl-regexp "foo.*bar"
1213 '
1214
1215 test_expect_success PCRE 'grep -P pattern' '
1216         git grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1217         test_cmp expected actual
1218 '
1219
1220 test_expect_success LIBPCRE2 "grep -P with (*NO_JIT) doesn't error out" '
1221         git grep -P "(*NO_JIT)\p{Ps}.*?\p{Pe}" hello.c >actual &&
1222         test_cmp expected actual
1223
1224 '
1225
1226 test_expect_success !PCRE 'grep -P pattern errors without PCRE' '
1227         test_must_fail git grep -P "foo.*bar"
1228 '
1229
1230 test_expect_success 'grep pattern with grep.extendedRegexp=true' '
1231         test_must_fail git -c grep.extendedregexp=true \
1232                 grep "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1233         test_must_be_empty actual
1234 '
1235
1236 test_expect_success PCRE 'grep -P pattern with grep.extendedRegexp=true' '
1237         git -c grep.extendedregexp=true \
1238                 grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1239         test_cmp expected actual
1240 '
1241
1242 test_expect_success PCRE 'grep -P -v pattern' '
1243         {
1244                 echo "ab:a+b*c"
1245                 echo "ab:a+bc"
1246         } >expected &&
1247         git grep -P -v "abc" ab >actual &&
1248         test_cmp expected actual
1249 '
1250
1251 test_expect_success PCRE 'grep -P -i pattern' '
1252         cat >expected <<-EOF &&
1253         hello.c:        printf("Hello world.\n");
1254         EOF
1255         git grep -P -i "PRINTF\([^\d]+\)" hello.c >actual &&
1256         test_cmp expected actual
1257 '
1258
1259 test_expect_success PCRE 'grep -P -w pattern' '
1260         {
1261                 echo "hello_world:Hello world"
1262                 echo "hello_world:HeLLo world"
1263         } >expected &&
1264         git grep -P -w "He((?i)ll)o" hello_world >actual &&
1265         test_cmp expected actual
1266 '
1267
1268 test_expect_success PCRE 'grep -P backreferences work (the PCRE NO_AUTO_CAPTURE flag is not set)' '
1269         git grep -P -h "(?P<one>.)(?P=one)" hello_world >actual &&
1270         test_cmp hello_world actual &&
1271         git grep -P -h "(.)\1" hello_world >actual &&
1272         test_cmp hello_world actual
1273 '
1274
1275 test_expect_success 'grep -G invalidpattern properly dies ' '
1276         test_must_fail git grep -G "a["
1277 '
1278
1279 test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '
1280         test_must_fail git -c grep.patterntype=basic grep "a["
1281 '
1282
1283 test_expect_success 'grep -E invalidpattern properly dies ' '
1284         test_must_fail git grep -E "a["
1285 '
1286
1287 test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '
1288         test_must_fail git -c grep.patterntype=extended grep "a["
1289 '
1290
1291 test_expect_success PCRE 'grep -P invalidpattern properly dies ' '
1292         test_must_fail git grep -P "a["
1293 '
1294
1295 test_expect_success PCRE 'grep invalidpattern properly dies with grep.patternType=perl' '
1296         test_must_fail git -c grep.patterntype=perl grep "a["
1297 '
1298
1299 test_expect_success 'grep -G -E -F pattern' '
1300         echo "ab:a+b*c" >expected &&
1301         git grep -G -E -F "a+b*c" ab >actual &&
1302         test_cmp expected actual
1303 '
1304
1305 test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '
1306         echo "ab:a+b*c" >expected &&
1307         git \
1308                 -c grep.patterntype=basic \
1309                 -c grep.patterntype=extended \
1310                 -c grep.patterntype=fixed \
1311                 grep "a+b*c" ab >actual &&
1312         test_cmp expected actual
1313 '
1314
1315 test_expect_success 'grep -E -F -G pattern' '
1316         echo "ab:a+bc" >expected &&
1317         git grep -E -F -G "a+b*c" ab >actual &&
1318         test_cmp expected actual
1319 '
1320
1321 test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '
1322         echo "ab:a+bc" >expected &&
1323         git \
1324                 -c grep.patterntype=extended \
1325                 -c grep.patterntype=fixed \
1326                 -c grep.patterntype=basic \
1327                 grep "a+b*c" ab >actual &&
1328         test_cmp expected actual
1329 '
1330
1331 test_expect_success 'grep -F -G -E pattern' '
1332         echo "ab:abc" >expected &&
1333         git grep -F -G -E "a+b*c" ab >actual &&
1334         test_cmp expected actual
1335 '
1336
1337 test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '
1338         echo "ab:abc" >expected &&
1339         git \
1340                 -c grep.patterntype=fixed \
1341                 -c grep.patterntype=basic \
1342                 -c grep.patterntype=extended \
1343                 grep "a+b*c" ab >actual &&
1344         test_cmp expected actual
1345 '
1346
1347 test_expect_success 'grep -G -F -P -E pattern' '
1348         echo "d0:d" >expected &&
1349         git grep -G -F -P -E "[\d]" d0 >actual &&
1350         test_cmp expected actual
1351 '
1352
1353 test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '
1354         echo "d0:d" >expected &&
1355         git \
1356                 -c grep.patterntype=fixed \
1357                 -c grep.patterntype=basic \
1358                 -c grep.patterntype=perl \
1359                 -c grep.patterntype=extended \
1360                 grep "[\d]" d0 >actual &&
1361         test_cmp expected actual
1362 '
1363
1364 test_expect_success PCRE 'grep -G -F -E -P pattern' '
1365         echo "d0:0" >expected &&
1366         git grep -G -F -E -P "[\d]" d0 >actual &&
1367         test_cmp expected actual
1368 '
1369
1370 test_expect_success PCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '
1371         echo "d0:0" >expected &&
1372         git \
1373                 -c grep.patterntype=fixed \
1374                 -c grep.patterntype=basic \
1375                 -c grep.patterntype=extended \
1376                 -c grep.patterntype=perl \
1377                 grep "[\d]" d0 >actual &&
1378         test_cmp expected actual
1379 '
1380
1381 test_expect_success PCRE 'grep -P pattern with grep.patternType=fixed' '
1382         echo "ab:a+b*c" >expected &&
1383         git \
1384                 -c grep.patterntype=fixed \
1385                 grep -P "a\x{2b}b\x{2a}c" ab >actual &&
1386         test_cmp expected actual
1387 '
1388
1389 test_expect_success 'grep -F pattern with grep.patternType=basic' '
1390         echo "ab:a+b*c" >expected &&
1391         git \
1392                 -c grep.patterntype=basic \
1393                 grep -F "*c" ab >actual &&
1394         test_cmp expected actual
1395 '
1396
1397 test_expect_success 'grep -G pattern with grep.patternType=fixed' '
1398         {
1399                 echo "ab:a+b*c"
1400                 echo "ab:a+bc"
1401         } >expected &&
1402         git \
1403                 -c grep.patterntype=fixed \
1404                 grep -G "a+b" ab >actual &&
1405         test_cmp expected actual
1406 '
1407
1408 test_expect_success 'grep -E pattern with grep.patternType=fixed' '
1409         {
1410                 echo "ab:a+b*c"
1411                 echo "ab:a+bc"
1412                 echo "ab:abc"
1413         } >expected &&
1414         git \
1415                 -c grep.patterntype=fixed \
1416                 grep -E "a+" ab >actual &&
1417         test_cmp expected actual
1418 '
1419
1420 cat >expected <<EOF
1421 hello.c<RED>:<RESET>int main(int argc, const char **argv)
1422 hello.c<RED>-<RESET>{
1423 <RED>--<RESET>
1424 hello.c<RED>:<RESET>    /* char ?? */
1425 hello.c<RED>-<RESET>}
1426 <RED>--<RESET>
1427 hello_world<RED>:<RESET>Hello_world
1428 hello_world<RED>-<RESET>HeLLo_world
1429 EOF
1430
1431 test_expect_success 'grep --color, separator' '
1432         test_config color.grep.context          normal &&
1433         test_config color.grep.filename         normal &&
1434         test_config color.grep.function         normal &&
1435         test_config color.grep.linenumber       normal &&
1436         test_config color.grep.match            normal &&
1437         test_config color.grep.selected         normal &&
1438         test_config color.grep.separator        red &&
1439
1440         git grep --color=always -A1 -e char -e lo_w hello.c hello_world |
1441         test_decode_color >actual &&
1442         test_cmp expected actual
1443 '
1444
1445 cat >expected <<EOF
1446 hello.c:int main(int argc, const char **argv)
1447 hello.c:        /* char ?? */
1448
1449 hello_world:Hello_world
1450 EOF
1451
1452 test_expect_success 'grep --break' '
1453         git grep --break -e char -e lo_w hello.c hello_world >actual &&
1454         test_cmp expected actual
1455 '
1456
1457 cat >expected <<EOF
1458 hello.c:int main(int argc, const char **argv)
1459 hello.c-{
1460 --
1461 hello.c:        /* char ?? */
1462 hello.c-}
1463
1464 hello_world:Hello_world
1465 hello_world-HeLLo_world
1466 EOF
1467
1468 test_expect_success 'grep --break with context' '
1469         git grep --break -A1 -e char -e lo_w hello.c hello_world >actual &&
1470         test_cmp expected actual
1471 '
1472
1473 cat >expected <<EOF
1474 hello.c
1475 int main(int argc, const char **argv)
1476         /* char ?? */
1477 hello_world
1478 Hello_world
1479 EOF
1480
1481 test_expect_success 'grep --heading' '
1482         git grep --heading -e char -e lo_w hello.c hello_world >actual &&
1483         test_cmp expected actual
1484 '
1485
1486 cat >expected <<EOF
1487 <BOLD;GREEN>hello.c<RESET>
1488 4:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv)
1489 8:      /* <BLACK;BYELLOW>char<RESET> ?? */
1490
1491 <BOLD;GREEN>hello_world<RESET>
1492 3:Hel<BLACK;BYELLOW>lo_w<RESET>orld
1493 EOF
1494
1495 test_expect_success 'mimic ack-grep --group' '
1496         test_config color.grep.context          normal &&
1497         test_config color.grep.filename         "bold green" &&
1498         test_config color.grep.function         normal &&
1499         test_config color.grep.linenumber       normal &&
1500         test_config color.grep.match            "black yellow" &&
1501         test_config color.grep.selected         normal &&
1502         test_config color.grep.separator        normal &&
1503
1504         git grep --break --heading -n --color \
1505                 -e char -e lo_w hello.c hello_world |
1506         test_decode_color >actual &&
1507         test_cmp expected actual
1508 '
1509
1510 cat >expected <<EOF
1511 space: line with leading space1
1512 space: line with leading space2
1513 space: line with leading space3
1514 EOF
1515
1516 test_expect_success PCRE 'grep -E "^ "' '
1517         git grep -E "^ " space >actual &&
1518         test_cmp expected actual
1519 '
1520
1521 test_expect_success PCRE 'grep -P "^ "' '
1522         git grep -P "^ " space >actual &&
1523         test_cmp expected actual
1524 '
1525
1526 cat >expected <<EOF
1527 space-line without leading space1
1528 space: line <RED>with <RESET>leading space1
1529 space: line <RED>with <RESET>leading <RED>space2<RESET>
1530 space: line <RED>with <RESET>leading space3
1531 space:line without leading <RED>space2<RESET>
1532 EOF
1533
1534 test_expect_success 'grep --color -e A -e B with context' '
1535         test_config color.grep.context          normal &&
1536         test_config color.grep.filename         normal &&
1537         test_config color.grep.function         normal &&
1538         test_config color.grep.linenumber       normal &&
1539         test_config color.grep.matchContext     normal &&
1540         test_config color.grep.matchSelected    red &&
1541         test_config color.grep.selected         normal &&
1542         test_config color.grep.separator        normal &&
1543
1544         git grep --color=always -C2 -e "with " -e space2  space |
1545         test_decode_color >actual &&
1546         test_cmp expected actual
1547 '
1548
1549 cat >expected <<EOF
1550 space-line without leading space1
1551 space- line with leading space1
1552 space: line <RED>with <RESET>leading <RED>space2<RESET>
1553 space- line with leading space3
1554 space-line without leading space2
1555 EOF
1556
1557 test_expect_success 'grep --color -e A --and -e B with context' '
1558         test_config color.grep.context          normal &&
1559         test_config color.grep.filename         normal &&
1560         test_config color.grep.function         normal &&
1561         test_config color.grep.linenumber       normal &&
1562         test_config color.grep.matchContext     normal &&
1563         test_config color.grep.matchSelected    red &&
1564         test_config color.grep.selected         normal &&
1565         test_config color.grep.separator        normal &&
1566
1567         git grep --color=always -C2 -e "with " --and -e space2  space |
1568         test_decode_color >actual &&
1569         test_cmp expected actual
1570 '
1571
1572 cat >expected <<EOF
1573 space-line without leading space1
1574 space: line <RED>with <RESET>leading space1
1575 space- line with leading space2
1576 space: line <RED>with <RESET>leading space3
1577 space-line without leading space2
1578 EOF
1579
1580 test_expect_success 'grep --color -e A --and --not -e B with context' '
1581         test_config color.grep.context          normal &&
1582         test_config color.grep.filename         normal &&
1583         test_config color.grep.function         normal &&
1584         test_config color.grep.linenumber       normal &&
1585         test_config color.grep.matchContext     normal &&
1586         test_config color.grep.matchSelected    red &&
1587         test_config color.grep.selected         normal &&
1588         test_config color.grep.separator        normal &&
1589
1590         git grep --color=always -C2 -e "with " --and --not -e space2  space |
1591         test_decode_color >actual &&
1592         test_cmp expected actual
1593 '
1594
1595 cat >expected <<EOF
1596 hello.c-
1597 hello.c=int main(int argc, const char **argv)
1598 hello.c-{
1599 hello.c:        pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n");
1600 hello.c-        return 0;
1601 hello.c-        /* char ?? */
1602 hello.c-}
1603 EOF
1604
1605 test_expect_success 'grep --color -e A --and -e B -p with context' '
1606         test_config color.grep.context          normal &&
1607         test_config color.grep.filename         normal &&
1608         test_config color.grep.function         normal &&
1609         test_config color.grep.linenumber       normal &&
1610         test_config color.grep.matchContext     normal &&
1611         test_config color.grep.matchSelected    red &&
1612         test_config color.grep.selected         normal &&
1613         test_config color.grep.separator        normal &&
1614
1615         git grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |
1616         test_decode_color >actual &&
1617         test_cmp expected actual
1618 '
1619
1620 test_expect_success 'grep can find things only in the work tree' '
1621         : >work-tree-only &&
1622         git add work-tree-only &&
1623         test_when_finished "git rm -f work-tree-only" &&
1624         echo "find in work tree" >work-tree-only &&
1625         git grep --quiet "find in work tree" &&
1626         test_must_fail git grep --quiet --cached "find in work tree" &&
1627         test_must_fail git grep --quiet "find in work tree" HEAD
1628 '
1629
1630 test_expect_success 'grep can find things only in the work tree (i-t-a)' '
1631         echo "intend to add this" >intend-to-add &&
1632         git add -N intend-to-add &&
1633         test_when_finished "git rm -f intend-to-add" &&
1634         git grep --quiet "intend to add this" &&
1635         test_must_fail git grep --quiet --cached "intend to add this" &&
1636         test_must_fail git grep --quiet "intend to add this" HEAD
1637 '
1638
1639 test_expect_success 'grep does not search work tree with assume unchanged' '
1640         echo "intend to add this" >intend-to-add &&
1641         git add -N intend-to-add &&
1642         git update-index --assume-unchanged intend-to-add &&
1643         test_when_finished "git rm -f intend-to-add" &&
1644         test_must_fail git grep --quiet "intend to add this" &&
1645         test_must_fail git grep --quiet --cached "intend to add this" &&
1646         test_must_fail git grep --quiet "intend to add this" HEAD
1647 '
1648
1649 test_expect_success 'grep can find things only in the index' '
1650         echo "only in the index" >cache-this &&
1651         git add cache-this &&
1652         rm cache-this &&
1653         test_when_finished "git rm --cached cache-this" &&
1654         test_must_fail git grep --quiet "only in the index" &&
1655         git grep --quiet --cached "only in the index" &&
1656         test_must_fail git grep --quiet "only in the index" HEAD
1657 '
1658
1659 test_expect_success 'grep does not report i-t-a with -L --cached' '
1660         echo "intend to add this" >intend-to-add &&
1661         git add -N intend-to-add &&
1662         test_when_finished "git rm -f intend-to-add" &&
1663         git ls-files | grep -v "^intend-to-add\$" >expected &&
1664         git grep -L --cached "nonexistent_string" >actual &&
1665         test_cmp expected actual
1666 '
1667
1668 test_expect_success 'grep does not report i-t-a and assume unchanged with -L' '
1669         echo "intend to add this" >intend-to-add-assume-unchanged &&
1670         git add -N intend-to-add-assume-unchanged &&
1671         test_when_finished "git rm -f intend-to-add-assume-unchanged" &&
1672         git update-index --assume-unchanged intend-to-add-assume-unchanged &&
1673         git ls-files | grep -v "^intend-to-add-assume-unchanged\$" >expected &&
1674         git grep -L "nonexistent_string" >actual &&
1675         test_cmp expected actual
1676 '
1677
1678 test_done