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