Merge git://git.kernel.org/pub/scm/gitk/gitk
[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 <stdio.h>
13 int main(int argc, const char **argv)
14 {
15         printf("Hello world.\n");
16         return 0;
17         /* char ?? */
18 }
19 EOF
20
21 test_expect_success setup '
22         {
23                 echo foo mmap bar
24                 echo foo_mmap bar
25                 echo foo_mmap bar mmap
26                 echo foo mmap bar_mmap
27                 echo foo_mmap bar mmap baz
28         } >file &&
29         echo vvv >v &&
30         echo ww w >w &&
31         echo x x xx x >x &&
32         echo y yy >y &&
33         echo zzz > z &&
34         mkdir t &&
35         echo test >t/t &&
36         echo vvv >t/v &&
37         mkdir t/a &&
38         echo vvv >t/a/v &&
39         git add . &&
40         test_tick &&
41         git commit -m initial
42 '
43
44 test_expect_success 'grep should not segfault with a bad input' '
45         test_must_fail git grep "("
46 '
47
48 for H in HEAD ''
49 do
50         case "$H" in
51         HEAD)   HC='HEAD:' L='HEAD' ;;
52         '')     HC= L='in working tree' ;;
53         esac
54
55         test_expect_success "grep -w $L" '
56                 {
57                         echo ${HC}file:1:foo mmap bar
58                         echo ${HC}file:3:foo_mmap bar mmap
59                         echo ${HC}file:4:foo mmap bar_mmap
60                         echo ${HC}file:5:foo_mmap bar mmap baz
61                 } >expected &&
62                 git grep -n -w -e mmap $H >actual &&
63                 test_cmp expected actual
64         '
65
66         test_expect_success "grep -w $L (w)" '
67                 : >expected &&
68                 test_must_fail git grep -n -w -e "^w" >actual &&
69                 test_cmp expected actual
70         '
71
72         test_expect_success "grep -w $L (x)" '
73                 {
74                         echo ${HC}x:1:x x xx x
75                 } >expected &&
76                 git grep -n -w -e "x xx* x" $H >actual &&
77                 test_cmp expected actual
78         '
79
80         test_expect_success "grep -w $L (y-1)" '
81                 {
82                         echo ${HC}y:1:y yy
83                 } >expected &&
84                 git grep -n -w -e "^y" $H >actual &&
85                 test_cmp expected actual
86         '
87
88         test_expect_success "grep -w $L (y-2)" '
89                 : >expected &&
90                 if git grep -n -w -e "^y y" $H >actual
91                 then
92                         echo should not have matched
93                         cat actual
94                         false
95                 else
96                         test_cmp expected actual
97                 fi
98         '
99
100         test_expect_success "grep -w $L (z)" '
101                 : >expected &&
102                 if git grep -n -w -e "^z" $H >actual
103                 then
104                         echo should not have matched
105                         cat actual
106                         false
107                 else
108                         test_cmp expected actual
109                 fi
110         '
111
112         test_expect_success "grep $L (t-1)" '
113                 echo "${HC}t/t:1:test" >expected &&
114                 git grep -n -e test $H >actual &&
115                 test_cmp expected actual
116         '
117
118         test_expect_success "grep $L (t-2)" '
119                 echo "${HC}t:1:test" >expected &&
120                 (
121                         cd t &&
122                         git grep -n -e test $H
123                 ) >actual &&
124                 test_cmp expected actual
125         '
126
127         test_expect_success "grep $L (t-3)" '
128                 echo "${HC}t/t:1:test" >expected &&
129                 (
130                         cd t &&
131                         git grep --full-name -n -e test $H
132                 ) >actual &&
133                 test_cmp expected actual
134         '
135
136         test_expect_success "grep -c $L (no /dev/null)" '
137                 ! git grep -c test $H | grep /dev/null
138         '
139
140         test_expect_success "grep --max-depth -1 $L" '
141                 {
142                         echo ${HC}t/a/v:1:vvv
143                         echo ${HC}t/v:1:vvv
144                         echo ${HC}v:1:vvv
145                 } >expected &&
146                 git grep --max-depth -1 -n -e vvv $H >actual &&
147                 test_cmp expected actual
148         '
149
150         test_expect_success "grep --max-depth 0 $L" '
151                 {
152                         echo ${HC}v:1:vvv
153                 } >expected &&
154                 git grep --max-depth 0 -n -e vvv $H >actual &&
155                 test_cmp expected actual
156         '
157
158         test_expect_success "grep --max-depth 0 -- '*' $L" '
159                 {
160                         echo ${HC}t/a/v:1:vvv
161                         echo ${HC}t/v:1:vvv
162                         echo ${HC}v:1:vvv
163                 } >expected &&
164                 git grep --max-depth 0 -n -e vvv $H -- "*" >actual &&
165                 test_cmp expected actual
166         '
167
168         test_expect_success "grep --max-depth 1 $L" '
169                 {
170                         echo ${HC}t/v:1:vvv
171                         echo ${HC}v:1:vvv
172                 } >expected &&
173                 git grep --max-depth 1 -n -e vvv $H >actual &&
174                 test_cmp expected actual
175         '
176
177         test_expect_success "grep --max-depth 0 -- t $L" '
178                 {
179                         echo ${HC}t/v:1:vvv
180                 } >expected &&
181                 git grep --max-depth 0 -n -e vvv $H -- t >actual &&
182                 test_cmp expected actual
183         '
184
185 done
186
187 cat >expected <<EOF
188 file:foo mmap bar_mmap
189 EOF
190
191 test_expect_success 'grep -e A --and -e B' '
192         git grep -e "foo mmap" --and -e bar_mmap >actual &&
193         test_cmp expected actual
194 '
195
196 cat >expected <<EOF
197 file:foo_mmap bar mmap
198 file:foo_mmap bar mmap baz
199 EOF
200
201
202 test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
203         git grep \( -e foo_ --or -e baz \) \
204                 --and -e " mmap" >actual &&
205         test_cmp expected actual
206 '
207
208 cat >expected <<EOF
209 file:foo mmap bar
210 EOF
211
212 test_expect_success 'grep -e A --and --not -e B' '
213         git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
214         test_cmp expected actual
215 '
216
217 test_expect_success 'grep should ignore GREP_OPTIONS' '
218         GREP_OPTIONS=-v git grep " mmap bar\$" >actual &&
219         test_cmp expected actual
220 '
221
222 test_expect_success 'grep -f, non-existent file' '
223         test_must_fail git grep -f patterns
224 '
225
226 cat >expected <<EOF
227 file:foo mmap bar
228 file:foo_mmap bar
229 file:foo_mmap bar mmap
230 file:foo mmap bar_mmap
231 file:foo_mmap bar mmap baz
232 EOF
233
234 cat >pattern <<EOF
235 mmap
236 EOF
237
238 test_expect_success 'grep -f, one pattern' '
239         git grep -f pattern >actual &&
240         test_cmp expected actual
241 '
242
243 cat >expected <<EOF
244 file:foo mmap bar
245 file:foo_mmap bar
246 file:foo_mmap bar mmap
247 file:foo mmap bar_mmap
248 file:foo_mmap bar mmap baz
249 t/a/v:vvv
250 t/v:vvv
251 v:vvv
252 EOF
253
254 cat >patterns <<EOF
255 mmap
256 vvv
257 EOF
258
259 test_expect_success 'grep -f, multiple patterns' '
260         git grep -f patterns >actual &&
261         test_cmp expected actual
262 '
263
264 cat >expected <<EOF
265 file:foo mmap bar
266 file:foo_mmap bar
267 file:foo_mmap bar mmap
268 file:foo mmap bar_mmap
269 file:foo_mmap bar mmap baz
270 t/a/v:vvv
271 t/v:vvv
272 v:vvv
273 EOF
274
275 cat >patterns <<EOF
276
277 mmap
278
279 vvv
280
281 EOF
282
283 test_expect_success 'grep -f, ignore empty lines' '
284         git grep -f patterns >actual &&
285         test_cmp expected actual
286 '
287
288 cat >expected <<EOF
289 y:y yy
290 --
291 z:zzz
292 EOF
293
294 test_expect_success 'grep -q, silently report matches' '
295         >empty &&
296         git grep -q mmap >actual &&
297         test_cmp empty actual &&
298         test_must_fail git grep -q qfwfq >actual &&
299         test_cmp empty actual
300 '
301
302 # Create 1024 file names that sort between "y" and "z" to make sure
303 # the two files are handled by different calls to an external grep.
304 # This depends on MAXARGS in builtin-grep.c being 1024 or less.
305 c32="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v"
306 test_expect_success 'grep -C1, hunk mark between files' '
307         for a in $c32; do for b in $c32; do : >y-$a$b; done; done &&
308         git add y-?? &&
309         git grep -C1 "^[yz]" >actual &&
310         test_cmp expected actual
311 '
312
313 test_expect_success 'grep -C1 hunk mark between files' '
314         git grep -C1 "^[yz]" >actual &&
315         test_cmp expected actual
316 '
317
318 test_expect_success 'log grep setup' '
319         echo a >>file &&
320         test_tick &&
321         GIT_AUTHOR_NAME="With * Asterisk" \
322         GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \
323         git commit -a -m "second" &&
324
325         echo a >>file &&
326         test_tick &&
327         git commit -a -m "third" &&
328
329         echo a >>file &&
330         test_tick &&
331         GIT_AUTHOR_NAME="Night Fall" \
332         GIT_AUTHOR_EMAIL="nitfol@frobozz.com" \
333         git commit -a -m "fourth"
334 '
335
336 test_expect_success 'log grep (1)' '
337         git log --author=author --pretty=tformat:%s >actual &&
338         ( echo third ; echo initial ) >expect &&
339         test_cmp expect actual
340 '
341
342 test_expect_success 'log grep (2)' '
343         git log --author=" * " -F --pretty=tformat:%s >actual &&
344         ( echo second ) >expect &&
345         test_cmp expect actual
346 '
347
348 test_expect_success 'log grep (3)' '
349         git log --author="^A U" --pretty=tformat:%s >actual &&
350         ( echo third ; echo initial ) >expect &&
351         test_cmp expect actual
352 '
353
354 test_expect_success 'log grep (4)' '
355         git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
356         ( echo second ) >expect &&
357         test_cmp expect actual
358 '
359
360 test_expect_success 'log grep (5)' '
361         git log --author=Thor -F --pretty=tformat:%s >actual &&
362         ( echo third ; echo initial ) >expect &&
363         test_cmp expect actual
364 '
365
366 test_expect_success 'log grep (6)' '
367         git log --author=-0700  --pretty=tformat:%s >actual &&
368         >expect &&
369         test_cmp expect actual
370 '
371
372 test_expect_success 'log --grep --author implicitly uses all-match' '
373         # grep matches initial and second but not third
374         # author matches only initial and third
375         git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
376         echo initial >expect &&
377         test_cmp expect actual
378 '
379
380 test_expect_success 'log with multiple --author uses union' '
381         git log --author="Thor" --author="Aster" --format=%s >actual &&
382         {
383             echo third && echo second && echo initial
384         } >expect &&
385         test_cmp expect actual
386 '
387
388 test_expect_success 'log with --grep and multiple --author uses all-match' '
389         git log --author="Thor" --author="Night" --grep=i --format=%s >actual &&
390         {
391             echo third && echo initial
392         } >expect &&
393         test_cmp expect actual
394 '
395
396 test_expect_success 'log with --grep and multiple --author uses all-match' '
397         git log --author="Thor" --author="Night" --grep=q --format=%s >actual &&
398         >expect &&
399         test_cmp expect actual
400 '
401
402 test_expect_success 'grep with CE_VALID file' '
403         git update-index --assume-unchanged t/t &&
404         rm t/t &&
405         test "$(git grep test)" = "t/t:test" &&
406         git update-index --no-assume-unchanged t/t &&
407         git checkout t/t
408 '
409
410 cat >expected <<EOF
411 hello.c=#include <stdio.h>
412 hello.c:        return 0;
413 EOF
414
415 test_expect_success 'grep -p with userdiff' '
416         git config diff.custom.funcname "^#" &&
417         echo "hello.c diff=custom" >.gitattributes &&
418         git grep -p return >actual &&
419         test_cmp expected actual
420 '
421
422 cat >expected <<EOF
423 hello.c=int main(int argc, const char **argv)
424 hello.c:        return 0;
425 EOF
426
427 test_expect_success 'grep -p' '
428         rm -f .gitattributes &&
429         git grep -p return >actual &&
430         test_cmp expected actual
431 '
432
433 cat >expected <<EOF
434 hello.c-#include <stdio.h>
435 hello.c=int main(int argc, const char **argv)
436 hello.c-{
437 hello.c-        printf("Hello world.\n");
438 hello.c:        return 0;
439 EOF
440
441 test_expect_success 'grep -p -B5' '
442         git grep -p -B5 return >actual &&
443         test_cmp expected actual
444 '
445
446 test_expect_success 'grep from a subdirectory to search wider area (1)' '
447         mkdir -p s &&
448         (
449                 cd s && git grep "x x x" ..
450         )
451 '
452
453 test_expect_success 'grep from a subdirectory to search wider area (2)' '
454         mkdir -p s &&
455         (
456                 cd s || exit 1
457                 ( git grep xxyyzz .. >out ; echo $? >status )
458                 ! test -s out &&
459                 test 1 = $(cat status)
460         )
461 '
462
463 cat >expected <<EOF
464 hello.c:int main(int argc, const char **argv)
465 EOF
466
467 test_expect_success 'grep -Fi' '
468         git grep -Fi "CHAR *" >actual &&
469         test_cmp expected actual
470 '
471
472 test_expect_success 'outside of git repository' '
473         rm -fr non &&
474         mkdir -p non/git/sub &&
475         echo hello >non/git/file1 &&
476         echo world >non/git/sub/file2 &&
477         echo ".*o*" >non/git/.gitignore &&
478         {
479                 echo file1:hello &&
480                 echo sub/file2:world
481         } >non/expect.full &&
482         echo file2:world >non/expect.sub &&
483         (
484                 GIT_CEILING_DIRECTORIES="$(pwd)/non/git" &&
485                 export GIT_CEILING_DIRECTORIES &&
486                 cd non/git &&
487                 test_must_fail git grep o &&
488                 git grep --no-index o >../actual.full &&
489                 test_cmp ../expect.full ../actual.full
490                 cd sub &&
491                 test_must_fail git grep o &&
492                 git grep --no-index o >../../actual.sub &&
493                 test_cmp ../../expect.sub ../../actual.sub
494         )
495 '
496
497 test_expect_success 'inside git repository but with --no-index' '
498         rm -fr is &&
499         mkdir -p is/git/sub &&
500         echo hello >is/git/file1 &&
501         echo world >is/git/sub/file2 &&
502         echo ".*o*" >is/git/.gitignore &&
503         {
504                 echo file1:hello &&
505                 echo sub/file2:world
506         } >is/expect.full &&
507         : >is/expect.empty &&
508         echo file2:world >is/expect.sub &&
509         (
510                 cd is/git &&
511                 git init &&
512                 test_must_fail git grep o >../actual.full &&
513                 test_cmp ../expect.empty ../actual.full &&
514                 git grep --no-index o >../actual.full &&
515                 test_cmp ../expect.full ../actual.full &&
516                 cd sub &&
517                 test_must_fail git grep o >../../actual.sub &&
518                 test_cmp ../../expect.empty ../../actual.sub &&
519                 git grep --no-index o >../../actual.sub &&
520                 test_cmp ../../expect.sub ../../actual.sub
521         )
522 '
523
524 test_expect_success 'setup double-dash tests' '
525 cat >double-dash <<EOF &&
526 --
527 ->
528 other
529 EOF
530 git add double-dash
531 '
532
533 cat >expected <<EOF
534 double-dash:->
535 EOF
536 test_expect_success 'grep -- pattern' '
537         git grep -- "->" >actual &&
538         test_cmp expected actual
539 '
540 test_expect_success 'grep -- pattern -- pathspec' '
541         git grep -- "->" -- double-dash >actual &&
542         test_cmp expected actual
543 '
544 test_expect_success 'grep -e pattern -- path' '
545         git grep -e "->" -- double-dash >actual &&
546         test_cmp expected actual
547 '
548
549 cat >expected <<EOF
550 double-dash:--
551 EOF
552 test_expect_success 'grep -e -- -- path' '
553         git grep -e -- -- double-dash >actual &&
554         test_cmp expected actual
555 '
556
557 test_done