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