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