]> git.ipfire.org Git - thirdparty/git.git/blame - t/t0008-ignores.sh
test: use unambigous leading path (/foo) for MSYS
[thirdparty/git.git] / t / t0008-ignores.sh
CommitLineData
368aa529
AS
1#!/bin/sh
2
3test_description=check-ignore
4
5. ./test-lib.sh
6
7init_vars () {
8 global_excludes="$(pwd)/global-excludes"
9}
10
11enable_global_excludes () {
12 init_vars &&
13 git config core.excludesfile "$global_excludes"
14}
15
16expect_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
26expect () {
27 expect_in stdout "$1"
28}
29
30expect_from_stdin () {
31 cat >"$HOME/expected-stdout"
32}
33
34test_stderr () {
35 expected="$1"
36 expect_in stderr "$1" &&
37 test_cmp "$HOME/expected-stderr" "$HOME/stderr"
38}
39
40stderr_contains () {
41 regexp="$1"
42 if grep "$regexp" "$HOME/stderr"
43 then
44 return 0
45 else
46 echo "didn't find /$regexp/ in $HOME/stderr"
47 cat "$HOME/stderr"
48 return 1
49 fi
50}
51
52stderr_empty_on_success () {
53 expect_code="$1"
54 if test $expect_code = 0
55 then
56 test_stderr ""
57 else
58 # If we expect failure then stderr might or might not be empty
59 # due to --quiet - the caller can check its contents
60 return 0
61 fi
62}
63
64test_check_ignore () {
65 args="$1" expect_code="${2:-0}" global_args="$3"
66
67 init_vars &&
68 rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
69 echo git $global_args check-ignore $quiet_opt $verbose_opt $args \
70 >"$HOME/cmd" &&
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"
76}
77
68666546
AS
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.
82#
83# Arguments:
84# - (optional) prereqs for this test, e.g. 'SYMLINKS'
85# - test name
86# - output to expect from -v / --verbose mode
87# - code to run (should invoke test_check_ignore)
368aa529
AS
88test_expect_success_multi () {
89 prereq=
90 if test $# -eq 4
91 then
92 prereq=$1
93 shift
94 fi
95 testname="$1" expect_verbose="$2" code="$3"
96
97 expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
98
99 test_expect_success $prereq "$testname" '
100 expect "$expect" &&
101 eval "$code"
102 '
103
104 for quiet_opt in '-q' '--quiet'
105 do
106 test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
107 expect '' &&
108 $code
109 "
110 done
111 quiet_opt=
112
113 for verbose_opt in '-v' '--verbose'
114 do
115 test_expect_success $prereq "$testname${verbose_opt:+ with $verbose_opt}" "
116 expect '$expect_verbose' &&
117 $code
118 "
119 done
120 verbose_opt=
121}
122
123test_expect_success 'setup' '
124 init_vars &&
125 mkdir -p a/b/ignored-dir a/submodule b &&
126 if test_have_prereq SYMLINKS
127 then
128 ln -s b a/symlink
129 fi &&
130 (
131 cd a/submodule &&
132 git init &&
133 echo a >a &&
134 git add a &&
135 git commit -m"commit in submodule"
136 ) &&
137 git add a/submodule &&
138 cat <<-\EOF >.gitignore &&
139 one
140 ignored-*
c19387e7 141 top-level-dir/
368aa529 142 EOF
6f53feac
RS
143 for dir in . a
144 do
145 : >$dir/not-ignored &&
146 : >$dir/ignored-and-untracked &&
147 : >$dir/ignored-but-in-index
148 done &&
149 git add -f ignored-but-in-index a/ignored-but-in-index &&
368aa529
AS
150 cat <<-\EOF >a/.gitignore &&
151 two*
152 *three
153 EOF
154 cat <<-\EOF >a/b/.gitignore &&
155 four
156 five
157 # this comment should affect the line numbers
158 six
159 ignored-dir/
160 # and so should this blank line:
161
162 !on*
163 !two
164 EOF
165 echo "seven" >a/b/ignored-dir/.gitignore &&
166 test -n "$HOME" &&
167 cat <<-\EOF >"$global_excludes" &&
168 globalone
169 !globaltwo
170 globalthree
171 EOF
172 cat <<-\EOF >>.git/info/exclude
173 per-repo
174 EOF
175'
176
177############################################################################
178#
179# test invalid inputs
180
c19387e7
JH
181test_expect_success_multi '. corner-case' '' '
182 test_check_ignore . 1
183'
184
368aa529
AS
185test_expect_success_multi 'empty command line' '' '
186 test_check_ignore "" 128 &&
187 stderr_contains "fatal: no path specified"
188'
189
190test_expect_success_multi '--stdin with empty STDIN' '' '
191 test_check_ignore "--stdin" 1 </dev/null &&
192 if test -n "$quiet_opt"; then
193 test_stderr ""
194 else
195 test_stderr "no pathspec given."
196 fi
197'
198
199test_expect_success '-q with multiple args' '
200 expect "" &&
201 test_check_ignore "-q one two" 128 &&
202 stderr_contains "fatal: --quiet is only valid with a single pathname"
203'
204
205test_expect_success '--quiet with multiple args' '
206 expect "" &&
207 test_check_ignore "--quiet one two" 128 &&
208 stderr_contains "fatal: --quiet is only valid with a single pathname"
209'
210
211for verbose_opt in '-v' '--verbose'
212do
213 for quiet_opt in '-q' '--quiet'
214 do
215 test_expect_success "$quiet_opt $verbose_opt" "
216 expect '' &&
217 test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
218 stderr_contains 'fatal: cannot have both --quiet and --verbose'
219 "
220 done
221done
222
223test_expect_success '--quiet with multiple args' '
224 expect "" &&
225 test_check_ignore "--quiet one two" 128 &&
226 stderr_contains "fatal: --quiet is only valid with a single pathname"
227'
228
229test_expect_success_multi 'erroneous use of --' '' '
230 test_check_ignore "--" 128 &&
231 stderr_contains "fatal: no path specified"
232'
233
234test_expect_success_multi '--stdin with superfluous arg' '' '
235 test_check_ignore "--stdin foo" 128 &&
236 stderr_contains "fatal: cannot specify pathnames with --stdin"
237'
238
239test_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"
242'
243
244test_expect_success_multi '-z without --stdin' '' '
245 test_check_ignore "-z" 128 &&
246 stderr_contains "fatal: -z only makes sense with --stdin"
247'
248
249test_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"
252'
253
254test_expect_success_multi 'needs work tree' '' '
255 (
256 cd .git &&
257 test_check_ignore "foo" 128
258 ) &&
259 stderr_contains "fatal: This operation must be run in a work tree"
260'
261
262############################################################################
263#
264# test standard ignores
265
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
268# index does.
269
270for subdir in '' 'a/'
271do
272 if test -z "$subdir"
273 then
274 where="at top-level"
275 else
276 where="in subdir $subdir"
277 fi
278
279 test_expect_success_multi "non-existent file $where not ignored" '' "
280 test_check_ignore '${subdir}non-existent' 1
281 "
282
283 test_expect_success_multi "non-existent file $where ignored" \
284 ".gitignore:1:one ${subdir}one" "
285 test_check_ignore '${subdir}one'
286 "
287
288 test_expect_success_multi "existing untracked file $where not ignored" '' "
289 test_check_ignore '${subdir}not-ignored' 1
290 "
291
292 test_expect_success_multi "existing tracked file $where not ignored" '' "
293 test_check_ignore '${subdir}ignored-but-in-index' 1
294 "
295
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'
299 "
300done
301
302# Having established the above, from now on we mostly test against
303# files which do not exist in the working tree or index.
304
305test_expect_success 'sub-directory local ignore' '
306 expect "a/3-three" &&
307 test_check_ignore "a/3-three a/three-not-this-one"
308'
309
310test_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"
313'
314
315test_expect_success 'local ignore inside a sub-directory' '
316 expect "3-three" &&
317 (
318 cd a &&
319 test_check_ignore "3-three three-not-this-one"
320 )
321'
322test_expect_success 'local ignore inside a sub-directory with --verbose' '
323 expect "a/.gitignore:2:*three 3-three" &&
324 (
325 cd a &&
326 test_check_ignore "--verbose 3-three three-not-this-one"
327 )
328'
329
330test_expect_success_multi 'nested include' \
331 'a/b/.gitignore:8:!on* a/b/one' '
332 test_check_ignore "a/b/one"
333'
334
335############################################################################
336#
337# test ignored sub-directories
338
339test_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"
342'
343
344test_expect_success 'multiple files inside ignored sub-directory' '
345 expect_from_stdin <<-\EOF &&
346 a/b/ignored-dir/foo
347 a/b/ignored-dir/twoooo
348 a/b/ignored-dir/seven
349 EOF
350 test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
351'
352
353test_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
358 EOF
359 test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
360'
361
362test_expect_success 'cd to ignored sub-directory' '
363 expect_from_stdin <<-\EOF &&
364 foo
365 twoooo
366 ../one
367 seven
368 ../../one
369 EOF
370 (
371 cd a/b/ignored-dir &&
372 test_check_ignore "foo twoooo ../one seven ../../one"
373 )
374'
375
376test_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
383 EOF
384 (
385 cd a/b/ignored-dir &&
386 test_check_ignore "-v foo twoooo ../one seven ../../one"
387 )
388'
389
390############################################################################
391#
392# test handling of symlinks
393
394test_expect_success_multi SYMLINKS 'symlink' '' '
395 test_check_ignore "a/symlink" 1
396'
397
398test_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"
401'
402
403test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
404 (
405 cd a &&
406 test_check_ignore "symlink/foo" 128
407 ) &&
408 test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
409'
410
411############################################################################
412#
413# test handling of submodules
414
415test_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'\''"
418'
419
420test_expect_success_multi 'submodule from subdirectory' '' '
421 (
422 cd a &&
423 test_check_ignore "submodule/one" 128
424 ) &&
425 test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
426'
427
428############################################################################
429#
430# test handling of global ignore files
431
432test_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
437 EOF
438 test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
439'
440
441test_expect_success 'global ignore' '
442 enable_global_excludes &&
443 expect_from_stdin <<-\EOF &&
444 globalone
445 per-repo
446 globalthree
447 a/globalthree
448 a/per-repo
449 globaltwo
450 EOF
451 test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
452'
453
454test_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
463 EOF
464 test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
465'
466
467############################################################################
468#
469# test --stdin
470
471cat <<-\EOF >stdin
472 one
473 not-ignored
474 a/one
475 a/not-ignored
476 a/b/on
477 a/b/one
478 a/b/one one
479 "a/b/one two"
480 "a/b/one\"three"
481 a/b/not-ignored
482 a/b/two
483 a/b/twooo
484 globaltwo
485 a/globaltwo
486 a/b/globaltwo
487 b/globaltwo
488EOF
489cat <<-\EOF >expected-default
490 one
491 a/one
492 a/b/on
493 a/b/one
494 a/b/one one
495 a/b/one two
496 "a/b/one\"three"
497 a/b/two
498 a/b/twooo
499 globaltwo
500 a/globaltwo
501 a/b/globaltwo
502 b/globaltwo
503EOF
504cat <<-EOF >expected-verbose
505 .gitignore:1:one one
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
518EOF
519
520sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
521 tr "\n" "\0" >stdin0
522sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
523 tr "\n" "\0" >expected-default0
524sed -e 's/ "/ /' -e 's/\\//' -e 's/"$//' expected-verbose | \
525 tr ":\t\n" "\0" >expected-verbose0
526
527test_expect_success '--stdin' '
528 expect_from_stdin <expected-default &&
529 test_check_ignore "--stdin" <stdin
530'
531
532test_expect_success '--stdin -q' '
533 expect "" &&
534 test_check_ignore "-q --stdin" <stdin
535'
536
537test_expect_success '--stdin -v' '
538 expect_from_stdin <expected-verbose &&
539 test_check_ignore "-v --stdin" <stdin
540'
541
542for opts in '--stdin -z' '-z --stdin'
543do
544 test_expect_success "$opts" "
545 expect_from_stdin <expected-default0 &&
546 test_check_ignore '$opts' <stdin0
547 "
548
549 test_expect_success "$opts -q" "
550 expect "" &&
551 test_check_ignore '-q $opts' <stdin0
552 "
553
554 test_expect_success "$opts -v" "
555 expect_from_stdin <expected-verbose0 &&
556 test_check_ignore '-v $opts' <stdin0
557 "
558done
559
560cat <<-\EOF >stdin
561 ../one
562 ../not-ignored
563 one
564 not-ignored
565 b/on
566 b/one
567 b/one one
568 "b/one two"
569 "b/one\"three"
570 b/two
571 b/not-ignored
572 b/twooo
573 ../globaltwo
574 globaltwo
575 b/globaltwo
576 ../b/globaltwo
577EOF
578cat <<-\EOF >expected-default
579 ../one
580 one
581 b/on
582 b/one
583 b/one one
584 b/one two
585 "b/one\"three"
586 b/two
587 b/twooo
588 ../globaltwo
589 globaltwo
590 b/globaltwo
591 ../b/globaltwo
592EOF
593cat <<-EOF >expected-verbose
594 .gitignore:1:one ../one
595 .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
607EOF
608
609sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
610 tr "\n" "\0" >stdin0
611sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
612 tr "\n" "\0" >expected-default0
613sed -e 's/ "/ /' -e 's/\\//' -e 's/"$//' expected-verbose | \
614 tr ":\t\n" "\0" >expected-verbose0
615
616test_expect_success '--stdin from subdirectory' '
617 expect_from_stdin <expected-default &&
618 (
619 cd a &&
620 test_check_ignore "--stdin" <../stdin
621 )
622'
623
624test_expect_success '--stdin from subdirectory with -v' '
625 expect_from_stdin <expected-verbose &&
626 (
627 cd a &&
628 test_check_ignore "--stdin -v" <../stdin
629 )
630'
631
632for opts in '--stdin -z' '-z --stdin'
633do
634 test_expect_success "$opts from subdirectory" '
635 expect_from_stdin <expected-default0 &&
636 (
637 cd a &&
638 test_check_ignore "'"$opts"'" <../stdin0
639 )
640 '
641
642 test_expect_success "$opts from subdirectory with -v" '
643 expect_from_stdin <expected-verbose0 &&
644 (
645 cd a &&
646 test_check_ignore "'"$opts"' -v" <../stdin0
647 )
648 '
649done
650
651
652test_done