Merge branch 'jk/shortlog-tolerate-broken-commit'
[git] / t / t0008-ignores.sh
1 #!/bin/sh
2
3 test_description=check-ignore
4
5 . ./test-lib.sh
6
7 init_vars () {
8         global_excludes="$(pwd)/global-excludes"
9 }
10
11 enable_global_excludes () {
12         init_vars &&
13         git config core.excludesfile "$global_excludes"
14 }
15
16 expect_in () {
17         dest="$HOME/expected-$1" text="$2"
18         if test -z "$text"
19         then
20                 >"$dest" # avoid newline
21         else
22                 echo "$text" >"$dest"
23         fi
24 }
25
26 expect () {
27         expect_in stdout "$1"
28 }
29
30 expect_from_stdin () {
31         cat >"$HOME/expected-stdout"
32 }
33
34 test_stderr () {
35         expected="$1"
36         expect_in stderr "$1" &&
37         test_cmp "$HOME/expected-stderr" "$HOME/stderr"
38 }
39
40 stderr_contains () {
41         regexp="$1"
42         if grep "$regexp" "$HOME/stderr"
43         then
44                 return 0
45         else
46                 echo "didn't find /$regexp/ in $HOME/stderr"
47                 cat "$HOME/stderr"
48                 return 1
49         fi
50 }
51
52 stderr_empty_on_success () {
53         expect_code="$1"
54         if test $expect_code = 0
55         then
56                 test_stderr ""
57         else
58                 # If we expect failure then stderr might or might not be empty
59                 # due to --quiet - the caller can check its contents
60                 return 0
61         fi
62 }
63
64 test_check_ignore () {
65         args="$1" expect_code="${2:-0}" global_args="$3"
66
67         init_vars &&
68         rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
69         echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
70                 >"$HOME/cmd" &&
71         echo "$expect_code" >"$HOME/expected-exit-code" &&
72         test_expect_code "$expect_code" \
73                 git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $no_index_opt $args \
74                 >"$HOME/stdout" 2>"$HOME/stderr" &&
75         test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
76         stderr_empty_on_success "$expect_code"
77 }
78
79 # Runs the same code with 4 different levels of output verbosity:
80 #
81 #   1. with -q / --quiet
82 #   2. with default verbosity
83 #   3. with -v / --verbose
84 #   4. with -v / --verbose, *and* -n / --non-matching
85 #
86 # expecting success each time.  Takes advantage of the fact that
87 # check-ignore --verbose output is the same as normal output except
88 # for the extra first column.
89 #
90 # A parameter is used to determine if the tests are run with the
91 # normal case (using the index), or with the --no-index option.
92 #
93 # Arguments:
94 #   - (optional) prereqs for this test, e.g. 'SYMLINKS'
95 #   - test name
96 #   - output to expect from the fourth verbosity mode (the output
97 #     from the other verbosity modes is automatically inferred
98 #     from this value)
99 #   - code to run (should invoke test_check_ignore)
100 #   - index option: --index or --no-index
101 test_expect_success_multiple () {
102         prereq=
103         if test $# -eq 5
104         then
105                 prereq=$1
106                 shift
107         fi
108         if test "$4" = "--index"
109         then
110                 no_index_opt=
111         else
112                 no_index_opt=$4
113         fi
114         testname="$1" expect_all="$2" code="$3"
115
116         expect_verbose=$( echo "$expect_all" | grep -v '^::     ' )
117         expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
118
119         test_expect_success $prereq "$testname${no_index_opt:+ with $no_index_opt}" '
120                 expect "$expect" &&
121                 eval "$code"
122         '
123
124         # --quiet is only valid when a single pattern is passed
125         if test $( echo "$expect_all" | wc -l ) = 1
126         then
127                 for quiet_opt in '-q' '--quiet'
128                 do
129                         opts="${no_index_opt:+$no_index_opt }$quiet_opt"
130                         test_expect_success $prereq "$testname${opts:+ with $opts}" "
131                         expect '' &&
132                         $code
133                 "
134                 done
135                 quiet_opt=
136         fi
137
138         for verbose_opt in '-v' '--verbose'
139         do
140                 for non_matching_opt in '' '-n' '--non-matching'
141                 do
142                         if test -n "$non_matching_opt"
143                         then
144                                 my_expect="$expect_all"
145                         else
146                                 my_expect="$expect_verbose"
147                         fi
148
149                         test_code="
150                                 expect '$my_expect' &&
151                                 $code
152                         "
153                         opts="${no_index_opt:+$no_index_opt }$verbose_opt${non_matching_opt:+ $non_matching_opt}"
154                         test_expect_success $prereq "$testname${opts:+ with $opts}" "$test_code"
155                 done
156         done
157         verbose_opt=
158         non_matching_opt=
159         no_index_opt=
160 }
161
162 test_expect_success_multi () {
163         test_expect_success_multiple "$@" "--index"
164 }
165
166 test_expect_success_no_index_multi () {
167         test_expect_success_multiple "$@" "--no-index"
168 }
169
170 test_expect_success 'setup' '
171         init_vars &&
172         mkdir -p a/b/ignored-dir a/submodule b &&
173         if test_have_prereq SYMLINKS
174         then
175                 ln -s b a/symlink
176         fi &&
177         (
178                 cd a/submodule &&
179                 git init &&
180                 echo a >a &&
181                 git add a &&
182                 git commit -m"commit in submodule"
183         ) &&
184         git add a/submodule &&
185         cat <<-\EOF >.gitignore &&
186                 one
187                 ignored-*
188                 top-level-dir/
189         EOF
190         for dir in . a
191         do
192                 : >$dir/not-ignored &&
193                 : >$dir/ignored-and-untracked &&
194                 : >$dir/ignored-but-in-index
195         done &&
196         git add -f ignored-but-in-index a/ignored-but-in-index &&
197         cat <<-\EOF >a/.gitignore &&
198                 two*
199                 *three
200         EOF
201         cat <<-\EOF >a/b/.gitignore &&
202                 four
203                 five
204                 # this comment should affect the line numbers
205                 six
206                 ignored-dir/
207                 # and so should this blank line:
208
209                 !on*
210                 !two
211         EOF
212         echo "seven" >a/b/ignored-dir/.gitignore &&
213         test -n "$HOME" &&
214         cat <<-\EOF >"$global_excludes" &&
215                 globalone
216                 !globaltwo
217                 globalthree
218         EOF
219         cat <<-\EOF >>.git/info/exclude
220                 per-repo
221         EOF
222 '
223
224 ############################################################################
225 #
226 # test invalid inputs
227
228 test_expect_success_multi '. corner-case' '::   .' '
229         test_check_ignore . 1
230 '
231
232 test_expect_success_multi 'empty command line' '' '
233         test_check_ignore "" 128 &&
234         stderr_contains "fatal: no path specified"
235 '
236
237 test_expect_success_multi '--stdin with empty STDIN' '' '
238         test_check_ignore "--stdin" 1 </dev/null &&
239         test_stderr ""
240 '
241
242 test_expect_success '-q with multiple args' '
243         expect "" &&
244         test_check_ignore "-q one two" 128 &&
245         stderr_contains "fatal: --quiet is only valid with a single pathname"
246 '
247
248 test_expect_success '--quiet with multiple args' '
249         expect "" &&
250         test_check_ignore "--quiet one two" 128 &&
251         stderr_contains "fatal: --quiet is only valid with a single pathname"
252 '
253
254 for verbose_opt in '-v' '--verbose'
255 do
256         for quiet_opt in '-q' '--quiet'
257         do
258                 test_expect_success "$quiet_opt $verbose_opt" "
259                         expect '' &&
260                         test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
261                         stderr_contains 'fatal: cannot have both --quiet and --verbose'
262                 "
263         done
264 done
265
266 test_expect_success '--quiet with multiple args' '
267         expect "" &&
268         test_check_ignore "--quiet one two" 128 &&
269         stderr_contains "fatal: --quiet is only valid with a single pathname"
270 '
271
272 test_expect_success_multi 'erroneous use of --' '' '
273         test_check_ignore "--" 128 &&
274         stderr_contains "fatal: no path specified"
275 '
276
277 test_expect_success_multi '--stdin with superfluous arg' '' '
278         test_check_ignore "--stdin foo" 128 &&
279         stderr_contains "fatal: cannot specify pathnames with --stdin"
280 '
281
282 test_expect_success_multi '--stdin -z with superfluous arg' '' '
283         test_check_ignore "--stdin -z foo" 128 &&
284         stderr_contains "fatal: cannot specify pathnames with --stdin"
285 '
286
287 test_expect_success_multi '-z without --stdin' '' '
288         test_check_ignore "-z" 128 &&
289         stderr_contains "fatal: -z only makes sense with --stdin"
290 '
291
292 test_expect_success_multi '-z without --stdin and superfluous arg' '' '
293         test_check_ignore "-z foo" 128 &&
294         stderr_contains "fatal: -z only makes sense with --stdin"
295 '
296
297 test_expect_success_multi 'needs work tree' '' '
298         (
299                 cd .git &&
300                 test_check_ignore "foo" 128
301         ) &&
302         stderr_contains "fatal: This operation must be run in a work tree"
303 '
304
305 ############################################################################
306 #
307 # test standard ignores
308
309 # First make sure that the presence of a file in the working tree
310 # does not impact results, but that the presence of a file in the
311 # index does unless the --no-index option is used.
312
313 for subdir in '' 'a/'
314 do
315         if test -z "$subdir"
316         then
317                 where="at top-level"
318         else
319                 where="in subdir $subdir"
320         fi
321
322         test_expect_success_multi "non-existent file $where not ignored" \
323                 "::     ${subdir}non-existent" \
324                 "test_check_ignore '${subdir}non-existent' 1"
325
326         test_expect_success_no_index_multi "non-existent file $where not ignored" \
327                 "::     ${subdir}non-existent" \
328                 "test_check_ignore '${subdir}non-existent' 1"
329
330         test_expect_success_multi "non-existent file $where ignored" \
331                 ".gitignore:1:one       ${subdir}one" \
332                 "test_check_ignore '${subdir}one'"
333
334         test_expect_success_no_index_multi "non-existent file $where ignored" \
335                 ".gitignore:1:one       ${subdir}one" \
336                 "test_check_ignore '${subdir}one'"
337
338         test_expect_success_multi "existing untracked file $where not ignored" \
339                 "::     ${subdir}not-ignored" \
340                 "test_check_ignore '${subdir}not-ignored' 1"
341
342         test_expect_success_no_index_multi "existing untracked file $where not ignored" \
343                 "::     ${subdir}not-ignored" \
344                 "test_check_ignore '${subdir}not-ignored' 1"
345
346         test_expect_success_multi "existing tracked file $where not ignored" \
347                 "::     ${subdir}ignored-but-in-index" \
348                 "test_check_ignore '${subdir}ignored-but-in-index' 1"
349
350         test_expect_success_no_index_multi "existing tracked file $where shown as ignored" \
351                 ".gitignore:2:ignored-* ${subdir}ignored-but-in-index" \
352                 "test_check_ignore '${subdir}ignored-but-in-index'"
353
354         test_expect_success_multi "existing untracked file $where ignored" \
355                 ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
356                 "test_check_ignore '${subdir}ignored-and-untracked'"
357
358         test_expect_success_no_index_multi "existing untracked file $where ignored" \
359                 ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \
360                 "test_check_ignore '${subdir}ignored-and-untracked'"
361
362         test_expect_success_multi "mix of file types $where" \
363 "::     ${subdir}non-existent
364 .gitignore:1:one        ${subdir}one
365 ::      ${subdir}not-ignored
366 ::      ${subdir}ignored-but-in-index
367 .gitignore:2:ignored-*  ${subdir}ignored-and-untracked" \
368                 "test_check_ignore '
369                         ${subdir}non-existent
370                         ${subdir}one
371                         ${subdir}not-ignored
372                         ${subdir}ignored-but-in-index
373                         ${subdir}ignored-and-untracked'
374                 "
375
376         test_expect_success_no_index_multi "mix of file types $where" \
377 "::     ${subdir}non-existent
378 .gitignore:1:one        ${subdir}one
379 ::      ${subdir}not-ignored
380 .gitignore:2:ignored-*  ${subdir}ignored-but-in-index
381 .gitignore:2:ignored-*  ${subdir}ignored-and-untracked" \
382                 "test_check_ignore '
383                         ${subdir}non-existent
384                         ${subdir}one
385                         ${subdir}not-ignored
386                         ${subdir}ignored-but-in-index
387                         ${subdir}ignored-and-untracked'
388                 "
389 done
390
391 # Having established the above, from now on we mostly test against
392 # files which do not exist in the working tree or index.
393
394 test_expect_success 'sub-directory local ignore' '
395         expect "a/3-three" &&
396         test_check_ignore "a/3-three a/three-not-this-one"
397 '
398
399 test_expect_success 'sub-directory local ignore with --verbose'  '
400         expect "a/.gitignore:2:*three   a/3-three" &&
401         test_check_ignore "--verbose a/3-three a/three-not-this-one"
402 '
403
404 test_expect_success 'local ignore inside a sub-directory' '
405         expect "3-three" &&
406         (
407                 cd a &&
408                 test_check_ignore "3-three three-not-this-one"
409         )
410 '
411 test_expect_success 'local ignore inside a sub-directory with --verbose' '
412         expect "a/.gitignore:2:*three   3-three" &&
413         (
414                 cd a &&
415                 test_check_ignore "--verbose 3-three three-not-this-one"
416         )
417 '
418
419 test_expect_success_multi 'nested include' \
420         'a/b/.gitignore:8:!on*  a/b/one' '
421         test_check_ignore "a/b/one"
422 '
423
424 ############################################################################
425 #
426 # test ignored sub-directories
427
428 test_expect_success_multi 'ignored sub-directory' \
429         'a/b/.gitignore:5:ignored-dir/  a/b/ignored-dir' '
430         test_check_ignore "a/b/ignored-dir"
431 '
432
433 test_expect_success 'multiple files inside ignored sub-directory' '
434         expect_from_stdin <<-\EOF &&
435                 a/b/ignored-dir/foo
436                 a/b/ignored-dir/twoooo
437                 a/b/ignored-dir/seven
438         EOF
439         test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
440 '
441
442 test_expect_success 'multiple files inside ignored sub-directory with -v' '
443         expect_from_stdin <<-\EOF &&
444                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/foo
445                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/twoooo
446                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/seven
447         EOF
448         test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
449 '
450
451 test_expect_success 'cd to ignored sub-directory' '
452         expect_from_stdin <<-\EOF &&
453                 foo
454                 twoooo
455                 ../one
456                 seven
457                 ../../one
458         EOF
459         (
460                 cd a/b/ignored-dir &&
461                 test_check_ignore "foo twoooo ../one seven ../../one"
462         )
463 '
464
465 test_expect_success 'cd to ignored sub-directory with -v' '
466         expect_from_stdin <<-\EOF &&
467                 a/b/.gitignore:5:ignored-dir/   foo
468                 a/b/.gitignore:5:ignored-dir/   twoooo
469                 a/b/.gitignore:8:!on*   ../one
470                 a/b/.gitignore:5:ignored-dir/   seven
471                 .gitignore:1:one        ../../one
472         EOF
473         (
474                 cd a/b/ignored-dir &&
475                 test_check_ignore "-v foo twoooo ../one seven ../../one"
476         )
477 '
478
479 ############################################################################
480 #
481 # test handling of symlinks
482
483 test_expect_success_multi SYMLINKS 'symlink' '::        a/symlink' '
484         test_check_ignore "a/symlink" 1
485 '
486
487 test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
488         test_check_ignore "a/symlink/foo" 128 &&
489         test_stderr "fatal: pathspec '\''a/symlink/foo'\'' is beyond a symbolic link"
490 '
491
492 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
493         (
494                 cd a &&
495                 test_check_ignore "symlink/foo" 128
496         ) &&
497         test_stderr "fatal: pathspec '\''symlink/foo'\'' is beyond a symbolic link"
498 '
499
500 ############################################################################
501 #
502 # test handling of submodules
503
504 test_expect_success_multi 'submodule' '' '
505         test_check_ignore "a/submodule/one" 128 &&
506         test_stderr "fatal: Pathspec '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
507 '
508
509 test_expect_success_multi 'submodule from subdirectory' '' '
510         (
511                 cd a &&
512                 test_check_ignore "submodule/one" 128
513         ) &&
514         test_stderr "fatal: Pathspec '\''submodule/one'\'' is in submodule '\''a/submodule'\''"
515 '
516
517 ############################################################################
518 #
519 # test handling of global ignore files
520
521 test_expect_success 'global ignore not yet enabled' '
522         expect_from_stdin <<-\EOF &&
523                 .git/info/exclude:7:per-repo    per-repo
524                 a/.gitignore:2:*three   a/globalthree
525                 .git/info/exclude:7:per-repo    a/per-repo
526         EOF
527         test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
528 '
529
530 test_expect_success 'global ignore' '
531         enable_global_excludes &&
532         expect_from_stdin <<-\EOF &&
533                 globalone
534                 per-repo
535                 globalthree
536                 a/globalthree
537                 a/per-repo
538                 globaltwo
539         EOF
540         test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
541 '
542
543 test_expect_success 'global ignore with -v' '
544         enable_global_excludes &&
545         expect_from_stdin <<-EOF &&
546                 $global_excludes:1:globalone    globalone
547                 .git/info/exclude:7:per-repo    per-repo
548                 $global_excludes:3:globalthree  globalthree
549                 a/.gitignore:2:*three   a/globalthree
550                 .git/info/exclude:7:per-repo    a/per-repo
551                 $global_excludes:2:!globaltwo   globaltwo
552         EOF
553         test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
554 '
555
556 ############################################################################
557 #
558 # test --stdin
559
560 cat <<-\EOF >stdin
561         one
562         not-ignored
563         a/one
564         a/not-ignored
565         a/b/on
566         a/b/one
567         a/b/one one
568         "a/b/one two"
569         "a/b/one\"three"
570         a/b/not-ignored
571         a/b/two
572         a/b/twooo
573         globaltwo
574         a/globaltwo
575         a/b/globaltwo
576         b/globaltwo
577 EOF
578 cat <<-\EOF >expected-default
579         one
580         a/one
581         a/b/on
582         a/b/one
583         a/b/one one
584         a/b/one two
585         "a/b/one\"three"
586         a/b/two
587         a/b/twooo
588         globaltwo
589         a/globaltwo
590         a/b/globaltwo
591         b/globaltwo
592 EOF
593 cat <<-EOF >expected-verbose
594         .gitignore:1:one        one
595         .gitignore:1:one        a/one
596         a/b/.gitignore:8:!on*   a/b/on
597         a/b/.gitignore:8:!on*   a/b/one
598         a/b/.gitignore:8:!on*   a/b/one one
599         a/b/.gitignore:8:!on*   a/b/one two
600         a/b/.gitignore:8:!on*   "a/b/one\"three"
601         a/b/.gitignore:9:!two   a/b/two
602         a/.gitignore:1:two*     a/b/twooo
603         $global_excludes:2:!globaltwo   globaltwo
604         $global_excludes:2:!globaltwo   a/globaltwo
605         $global_excludes:2:!globaltwo   a/b/globaltwo
606         $global_excludes:2:!globaltwo   b/globaltwo
607 EOF
608
609 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
610         tr "\n" "\0" >stdin0
611 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
612         tr "\n" "\0" >expected-default0
613 sed -e 's/      "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
614         tr ":\t\n" "\0" >expected-verbose0
615
616 test_expect_success '--stdin' '
617         expect_from_stdin <expected-default &&
618         test_check_ignore "--stdin" <stdin
619 '
620
621 test_expect_success '--stdin -q' '
622         expect "" &&
623         test_check_ignore "-q --stdin" <stdin
624 '
625
626 test_expect_success '--stdin -v' '
627         expect_from_stdin <expected-verbose &&
628         test_check_ignore "-v --stdin" <stdin
629 '
630
631 for opts in '--stdin -z' '-z --stdin'
632 do
633         test_expect_success "$opts" "
634                 expect_from_stdin <expected-default0 &&
635                 test_check_ignore '$opts' <stdin0
636         "
637
638         test_expect_success "$opts -q" "
639                 expect "" &&
640                 test_check_ignore '-q $opts' <stdin0
641         "
642
643         test_expect_success "$opts -v" "
644                 expect_from_stdin <expected-verbose0 &&
645                 test_check_ignore '-v $opts' <stdin0
646         "
647 done
648
649 cat <<-\EOF >stdin
650         ../one
651         ../not-ignored
652         one
653         not-ignored
654         b/on
655         b/one
656         b/one one
657         "b/one two"
658         "b/one\"three"
659         b/two
660         b/not-ignored
661         b/twooo
662         ../globaltwo
663         globaltwo
664         b/globaltwo
665         ../b/globaltwo
666         c/not-ignored
667 EOF
668 # N.B. we deliberately end STDIN with a non-matching pattern in order
669 # to test that the exit code indicates that one or more of the
670 # provided paths is ignored - in other words, that it represents an
671 # aggregation of all the results, not just the final result.
672
673 cat <<-EOF >expected-all
674         .gitignore:1:one        ../one
675         ::      ../not-ignored
676         .gitignore:1:one        one
677         ::      not-ignored
678         a/b/.gitignore:8:!on*   b/on
679         a/b/.gitignore:8:!on*   b/one
680         a/b/.gitignore:8:!on*   b/one one
681         a/b/.gitignore:8:!on*   b/one two
682         a/b/.gitignore:8:!on*   "b/one\"three"
683         a/b/.gitignore:9:!two   b/two
684         ::      b/not-ignored
685         a/.gitignore:1:two*     b/twooo
686         $global_excludes:2:!globaltwo   ../globaltwo
687         $global_excludes:2:!globaltwo   globaltwo
688         $global_excludes:2:!globaltwo   b/globaltwo
689         $global_excludes:2:!globaltwo   ../b/globaltwo
690         ::      c/not-ignored
691 EOF
692 grep -v '^::    ' expected-all >expected-verbose
693 sed -e 's/.*    //' expected-verbose >expected-default
694
695 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
696         tr "\n" "\0" >stdin0
697 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
698         tr "\n" "\0" >expected-default0
699 sed -e 's/      "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
700         tr ":\t\n" "\0" >expected-verbose0
701
702 test_expect_success '--stdin from subdirectory' '
703         expect_from_stdin <expected-default &&
704         (
705                 cd a &&
706                 test_check_ignore "--stdin" <../stdin
707         )
708 '
709
710 test_expect_success '--stdin from subdirectory with -v' '
711         expect_from_stdin <expected-verbose &&
712         (
713                 cd a &&
714                 test_check_ignore "--stdin -v" <../stdin
715         )
716 '
717
718 test_expect_success '--stdin from subdirectory with -v -n' '
719         expect_from_stdin <expected-all &&
720         (
721                 cd a &&
722                 test_check_ignore "--stdin -v -n" <../stdin
723         )
724 '
725
726 for opts in '--stdin -z' '-z --stdin'
727 do
728         test_expect_success "$opts from subdirectory" '
729                 expect_from_stdin <expected-default0 &&
730                 (
731                         cd a &&
732                         test_check_ignore "'"$opts"'" <../stdin0
733                 )
734         '
735
736         test_expect_success "$opts from subdirectory with -v" '
737                 expect_from_stdin <expected-verbose0 &&
738                 (
739                         cd a &&
740                         test_check_ignore "'"$opts"' -v" <../stdin0
741                 )
742         '
743 done
744
745 test_expect_success PIPE 'streaming support for --stdin' '
746         mkfifo in out &&
747         (git check-ignore -n -v --stdin <in >out &) &&
748
749         # We cannot just "echo >in" because check-ignore would get EOF
750         # after echo exited; instead we open the descriptor in our
751         # shell, and then echo to the fd. We make sure to close it at
752         # the end, so that the subprocess does get EOF and dies
753         # properly.
754         #
755         # Similarly, we must keep "out" open so that check-ignore does
756         # not ever get SIGPIPE trying to write to us. Not only would that
757         # produce incorrect results, but then there would be no writer on the
758         # other end of the pipe, and we would potentially block forever trying
759         # to open it.
760         exec 9>in &&
761         exec 8<out &&
762         test_when_finished "exec 9>&-" &&
763         test_when_finished "exec 8<&-" &&
764         echo >&9 one &&
765         read response <&8 &&
766         echo "$response" | grep "^\.gitignore:1:one     one" &&
767         echo >&9 two &&
768         read response <&8 &&
769         echo "$response" | grep "^::    two"
770 '
771
772 test_done