3 test_description=check-ignore
8 global_excludes="$(pwd)/global-excludes"
11 enable_global_excludes () {
13 git config core.excludesfile "$global_excludes"
17 dest="$HOME/expected-$1" text="$2"
20 >"$dest" # avoid newline
30 expect_from_stdin () {
31 cat >"$HOME/expected-stdout"
36 expect_in stderr "$1" &&
37 test_cmp "$HOME/expected-stderr" "$HOME/stderr"
42 if grep "$regexp" "$HOME/stderr"
46 echo "didn't find /$regexp/ in $HOME/stderr"
52 stderr_empty_on_success () {
54 if test $expect_code = 0
58 # If we expect failure then stderr might or might not be empty
59 # due to --quiet - the caller can check its contents
64 test_check_ignore () {
65 args="$1" expect_code="${2:-0}" global_args="$3"
68 rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
69 echo git $global_args check-ignore $quiet_opt $verbose_opt $args \
71 test_expect_code "$expect_code" \
72 git $global_args check-ignore $quiet_opt $verbose_opt $args \
73 >"$HOME/stdout" 2>"$HOME/stderr" &&
74 test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
75 stderr_empty_on_success "$expect_code"
78 # Runs the same code with 3 different levels of output verbosity,
79 # expecting success each time. Takes advantage of the fact that
80 # check-ignore --verbose output is the same as normal output except
81 # for the extra first column.
84 # - (optional) prereqs for this test, e.g. 'SYMLINKS'
86 # - output to expect from -v / --verbose mode
87 # - code to run (should invoke test_check_ignore)
88 test_expect_success_multi () {
95 testname="$1" expect_verbose="$2" code="$3"
97 expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
99 test_expect_success $prereq "$testname" '
104 for quiet_opt in '-q' '--quiet'
106 test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
113 for verbose_opt in '-v' '--verbose'
115 test_expect_success $prereq "$testname${verbose_opt:+ with $verbose_opt}" "
116 expect '$expect_verbose' &&
123 test_expect_success 'setup' '
125 mkdir -p a/b/ignored-dir a/submodule b &&
126 if test_have_prereq SYMLINKS
135 git commit -m"commit in submodule"
137 git add a/submodule &&
138 cat <<-\EOF >.gitignore &&
145 : >$dir/not-ignored &&
146 : >$dir/ignored-and-untracked &&
147 : >$dir/ignored-but-in-index
149 git add -f ignored-but-in-index a/ignored-but-in-index &&
150 cat <<-\EOF >a/.gitignore &&
154 cat <<-\EOF >a/b/.gitignore &&
157 # this comment should affect the line numbers
160 # and so should this blank line:
165 echo "seven" >a/b/ignored-dir/.gitignore &&
167 cat <<-\EOF >"$global_excludes" &&
172 cat <<-\EOF >>.git/info/exclude
177 ############################################################################
179 # test invalid inputs
181 test_expect_success_multi '. corner-case' '' '
182 test_check_ignore . 1
185 test_expect_success_multi 'empty command line' '' '
186 test_check_ignore "" 128 &&
187 stderr_contains "fatal: no path specified"
190 test_expect_success_multi '--stdin with empty STDIN' '' '
191 test_check_ignore "--stdin" 1 </dev/null &&
192 if test -n "$quiet_opt"; then
195 test_stderr "no pathspec given."
199 test_expect_success '-q with multiple args' '
201 test_check_ignore "-q one two" 128 &&
202 stderr_contains "fatal: --quiet is only valid with a single pathname"
205 test_expect_success '--quiet with multiple args' '
207 test_check_ignore "--quiet one two" 128 &&
208 stderr_contains "fatal: --quiet is only valid with a single pathname"
211 for verbose_opt in '-v' '--verbose'
213 for quiet_opt in '-q' '--quiet'
215 test_expect_success "$quiet_opt $verbose_opt" "
217 test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
218 stderr_contains 'fatal: cannot have both --quiet and --verbose'
223 test_expect_success '--quiet with multiple args' '
225 test_check_ignore "--quiet one two" 128 &&
226 stderr_contains "fatal: --quiet is only valid with a single pathname"
229 test_expect_success_multi 'erroneous use of --' '' '
230 test_check_ignore "--" 128 &&
231 stderr_contains "fatal: no path specified"
234 test_expect_success_multi '--stdin with superfluous arg' '' '
235 test_check_ignore "--stdin foo" 128 &&
236 stderr_contains "fatal: cannot specify pathnames with --stdin"
239 test_expect_success_multi '--stdin -z with superfluous arg' '' '
240 test_check_ignore "--stdin -z foo" 128 &&
241 stderr_contains "fatal: cannot specify pathnames with --stdin"
244 test_expect_success_multi '-z without --stdin' '' '
245 test_check_ignore "-z" 128 &&
246 stderr_contains "fatal: -z only makes sense with --stdin"
249 test_expect_success_multi '-z without --stdin and superfluous arg' '' '
250 test_check_ignore "-z foo" 128 &&
251 stderr_contains "fatal: -z only makes sense with --stdin"
254 test_expect_success_multi 'needs work tree' '' '
257 test_check_ignore "foo" 128
259 stderr_contains "fatal: This operation must be run in a work tree"
262 ############################################################################
264 # test standard ignores
266 # First make sure that the presence of a file in the working tree
267 # does not impact results, but that the presence of a file in the
270 for subdir in '' 'a/'
276 where="in subdir $subdir"
279 test_expect_success_multi "non-existent file $where not ignored" '' "
280 test_check_ignore '${subdir}non-existent' 1
283 test_expect_success_multi "non-existent file $where ignored" \
284 ".gitignore:1:one ${subdir}one" "
285 test_check_ignore '${subdir}one'
288 test_expect_success_multi "existing untracked file $where not ignored" '' "
289 test_check_ignore '${subdir}not-ignored' 1
292 test_expect_success_multi "existing tracked file $where not ignored" '' "
293 test_check_ignore '${subdir}ignored-but-in-index' 1
296 test_expect_success_multi "existing untracked file $where ignored" \
297 ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" "
298 test_check_ignore '${subdir}ignored-and-untracked'
302 # Having established the above, from now on we mostly test against
303 # files which do not exist in the working tree or index.
305 test_expect_success 'sub-directory local ignore' '
306 expect "a/3-three" &&
307 test_check_ignore "a/3-three a/three-not-this-one"
310 test_expect_success 'sub-directory local ignore with --verbose' '
311 expect "a/.gitignore:2:*three a/3-three" &&
312 test_check_ignore "--verbose a/3-three a/three-not-this-one"
315 test_expect_success 'local ignore inside a sub-directory' '
319 test_check_ignore "3-three three-not-this-one"
322 test_expect_success 'local ignore inside a sub-directory with --verbose' '
323 expect "a/.gitignore:2:*three 3-three" &&
326 test_check_ignore "--verbose 3-three three-not-this-one"
330 test_expect_success_multi 'nested include' \
331 'a/b/.gitignore:8:!on* a/b/one' '
332 test_check_ignore "a/b/one"
335 ############################################################################
337 # test ignored sub-directories
339 test_expect_success_multi 'ignored sub-directory' \
340 'a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir' '
341 test_check_ignore "a/b/ignored-dir"
344 test_expect_success 'multiple files inside ignored sub-directory' '
345 expect_from_stdin <<-\EOF &&
347 a/b/ignored-dir/twoooo
348 a/b/ignored-dir/seven
350 test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
353 test_expect_success 'multiple files inside ignored sub-directory with -v' '
354 expect_from_stdin <<-\EOF &&
355 a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/foo
356 a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/twoooo
357 a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/seven
359 test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
362 test_expect_success 'cd to ignored sub-directory' '
363 expect_from_stdin <<-\EOF &&
371 cd a/b/ignored-dir &&
372 test_check_ignore "foo twoooo ../one seven ../../one"
376 test_expect_success 'cd to ignored sub-directory with -v' '
377 expect_from_stdin <<-\EOF &&
378 a/b/.gitignore:5:ignored-dir/ foo
379 a/b/.gitignore:5:ignored-dir/ twoooo
380 a/b/.gitignore:8:!on* ../one
381 a/b/.gitignore:5:ignored-dir/ seven
382 .gitignore:1:one ../../one
385 cd a/b/ignored-dir &&
386 test_check_ignore "-v foo twoooo ../one seven ../../one"
390 ############################################################################
392 # test handling of symlinks
394 test_expect_success_multi SYMLINKS 'symlink' '' '
395 test_check_ignore "a/symlink" 1
398 test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
399 test_check_ignore "a/symlink/foo" 128 &&
400 test_stderr "fatal: '\''a/symlink/foo'\'' is beyond a symbolic link"
403 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
406 test_check_ignore "symlink/foo" 128
408 test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
411 ############################################################################
413 # test handling of submodules
415 test_expect_success_multi 'submodule' '' '
416 test_check_ignore "a/submodule/one" 128 &&
417 test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
420 test_expect_success_multi 'submodule from subdirectory' '' '
423 test_check_ignore "submodule/one" 128
425 test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
428 ############################################################################
430 # test handling of global ignore files
432 test_expect_success 'global ignore not yet enabled' '
433 expect_from_stdin <<-\EOF &&
434 .git/info/exclude:7:per-repo per-repo
435 a/.gitignore:2:*three a/globalthree
436 .git/info/exclude:7:per-repo a/per-repo
438 test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
441 test_expect_success 'global ignore' '
442 enable_global_excludes &&
443 expect_from_stdin <<-\EOF &&
451 test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
454 test_expect_success 'global ignore with -v' '
455 enable_global_excludes &&
456 expect_from_stdin <<-EOF &&
457 $global_excludes:1:globalone globalone
458 .git/info/exclude:7:per-repo per-repo
459 $global_excludes:3:globalthree globalthree
460 a/.gitignore:2:*three a/globalthree
461 .git/info/exclude:7:per-repo a/per-repo
462 $global_excludes:2:!globaltwo globaltwo
464 test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
467 ############################################################################
489 cat <<-\EOF >expected-default
504 cat <<-EOF >expected-verbose
506 .gitignore:1:one a/one
507 a/b/.gitignore:8:!on* a/b/on
508 a/b/.gitignore:8:!on* a/b/one
509 a/b/.gitignore:8:!on* a/b/one one
510 a/b/.gitignore:8:!on* a/b/one two
511 a/b/.gitignore:8:!on* "a/b/one\"three"
512 a/b/.gitignore:9:!two a/b/two
513 a/.gitignore:1:two* a/b/twooo
514 $global_excludes:2:!globaltwo globaltwo
515 $global_excludes:2:!globaltwo a/globaltwo
516 $global_excludes:2:!globaltwo a/b/globaltwo
517 $global_excludes:2:!globaltwo b/globaltwo
520 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
522 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
523 tr "\n" "\0" >expected-default0
524 sed -e 's/ "/ /' -e 's/\\//' -e 's/"$//' expected-verbose | \
525 tr ":\t\n" "\0" >expected-verbose0
527 test_expect_success '--stdin' '
528 expect_from_stdin <expected-default &&
529 test_check_ignore "--stdin" <stdin
532 test_expect_success '--stdin -q' '
534 test_check_ignore "-q --stdin" <stdin
537 test_expect_success '--stdin -v' '
538 expect_from_stdin <expected-verbose &&
539 test_check_ignore "-v --stdin" <stdin
542 for opts in '--stdin -z' '-z --stdin'
544 test_expect_success "$opts" "
545 expect_from_stdin <expected-default0 &&
546 test_check_ignore '$opts' <stdin0
549 test_expect_success "$opts -q" "
551 test_check_ignore '-q $opts' <stdin0
554 test_expect_success "$opts -v" "
555 expect_from_stdin <expected-verbose0 &&
556 test_check_ignore '-v $opts' <stdin0
578 cat <<-\EOF >expected-default
593 cat <<-EOF >expected-verbose
594 .gitignore:1:one ../one
596 a/b/.gitignore:8:!on* b/on
597 a/b/.gitignore:8:!on* b/one
598 a/b/.gitignore:8:!on* b/one one
599 a/b/.gitignore:8:!on* b/one two
600 a/b/.gitignore:8:!on* "b/one\"three"
601 a/b/.gitignore:9:!two b/two
602 a/.gitignore:1:two* b/twooo
603 $global_excludes:2:!globaltwo ../globaltwo
604 $global_excludes:2:!globaltwo globaltwo
605 $global_excludes:2:!globaltwo b/globaltwo
606 $global_excludes:2:!globaltwo ../b/globaltwo
609 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
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
616 test_expect_success '--stdin from subdirectory' '
617 expect_from_stdin <expected-default &&
620 test_check_ignore "--stdin" <../stdin
624 test_expect_success '--stdin from subdirectory with -v' '
625 expect_from_stdin <expected-verbose &&
628 test_check_ignore "--stdin -v" <../stdin
632 for opts in '--stdin -z' '-z --stdin'
634 test_expect_success "$opts from subdirectory" '
635 expect_from_stdin <expected-default0 &&
638 test_check_ignore "'"$opts"'" <../stdin0
642 test_expect_success "$opts from subdirectory with -v" '
643 expect_from_stdin <expected-verbose0 &&
646 test_check_ignore "'"$opts"' -v" <../stdin0