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