Merge branch 'sp/smart-http-content-type-check'
[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="$(pwd)/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_cmp "$HOME/expected-stderr" "$HOME/stderr"
38 }
39
40 stderr_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
52 stderr_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
64 test_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
78 test_expect_success_multi () {
79         prereq=
80         if test $# -eq 4
81         then
82                 prereq=$1
83                 shift
84         fi
85         testname="$1" expect_verbose="$2" code="$3"
86
87         expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
88
89         test_expect_success $prereq "$testname" '
90                 expect "$expect" &&
91                 eval "$code"
92         '
93
94         for quiet_opt in '-q' '--quiet'
95         do
96                 test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
97                         expect '' &&
98                         $code
99                 "
100         done
101         quiet_opt=
102
103         for verbose_opt in '-v' '--verbose'
104         do
105                 test_expect_success $prereq "$testname${verbose_opt:+ with $verbose_opt}" "
106                         expect '$expect_verbose' &&
107                         $code
108                 "
109         done
110         verbose_opt=
111 }
112
113 test_expect_success 'setup' '
114         init_vars &&
115         mkdir -p a/b/ignored-dir a/submodule b &&
116         if test_have_prereq SYMLINKS
117         then
118                 ln -s b a/symlink
119         fi &&
120         (
121                 cd a/submodule &&
122                 git init &&
123                 echo a >a &&
124                 git add a &&
125                 git commit -m"commit in submodule"
126         ) &&
127         git add a/submodule &&
128         cat <<-\EOF >.gitignore &&
129                 one
130                 ignored-*
131         EOF
132         for dir in . a
133         do
134                 : >$dir/not-ignored &&
135                 : >$dir/ignored-and-untracked &&
136                 : >$dir/ignored-but-in-index
137         done &&
138         git add -f ignored-but-in-index a/ignored-but-in-index &&
139         cat <<-\EOF >a/.gitignore &&
140                 two*
141                 *three
142         EOF
143         cat <<-\EOF >a/b/.gitignore &&
144                 four
145                 five
146                 # this comment should affect the line numbers
147                 six
148                 ignored-dir/
149                 # and so should this blank line:
150
151                 !on*
152                 !two
153         EOF
154         echo "seven" >a/b/ignored-dir/.gitignore &&
155         test -n "$HOME" &&
156         cat <<-\EOF >"$global_excludes" &&
157                 globalone
158                 !globaltwo
159                 globalthree
160         EOF
161         cat <<-\EOF >>.git/info/exclude
162                 per-repo
163         EOF
164 '
165
166 ############################################################################
167 #
168 # test invalid inputs
169
170 test_expect_success_multi 'empty command line' '' '
171         test_check_ignore "" 128 &&
172         stderr_contains "fatal: no path specified"
173 '
174
175 test_expect_success_multi '--stdin with empty STDIN' '' '
176         test_check_ignore "--stdin" 1 </dev/null &&
177         if test -n "$quiet_opt"; then
178                 test_stderr ""
179         else
180                 test_stderr "no pathspec given."
181         fi
182 '
183
184 test_expect_success '-q with multiple args' '
185         expect "" &&
186         test_check_ignore "-q one two" 128 &&
187         stderr_contains "fatal: --quiet is only valid with a single pathname"
188 '
189
190 test_expect_success '--quiet with multiple args' '
191         expect "" &&
192         test_check_ignore "--quiet one two" 128 &&
193         stderr_contains "fatal: --quiet is only valid with a single pathname"
194 '
195
196 for verbose_opt in '-v' '--verbose'
197 do
198         for quiet_opt in '-q' '--quiet'
199         do
200                 test_expect_success "$quiet_opt $verbose_opt" "
201                         expect '' &&
202                         test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
203                         stderr_contains 'fatal: cannot have both --quiet and --verbose'
204                 "
205         done
206 done
207
208 test_expect_success '--quiet with multiple args' '
209         expect "" &&
210         test_check_ignore "--quiet one two" 128 &&
211         stderr_contains "fatal: --quiet is only valid with a single pathname"
212 '
213
214 test_expect_success_multi 'erroneous use of --' '' '
215         test_check_ignore "--" 128 &&
216         stderr_contains "fatal: no path specified"
217 '
218
219 test_expect_success_multi '--stdin with superfluous arg' '' '
220         test_check_ignore "--stdin foo" 128 &&
221         stderr_contains "fatal: cannot specify pathnames with --stdin"
222 '
223
224 test_expect_success_multi '--stdin -z with superfluous arg' '' '
225         test_check_ignore "--stdin -z foo" 128 &&
226         stderr_contains "fatal: cannot specify pathnames with --stdin"
227 '
228
229 test_expect_success_multi '-z without --stdin' '' '
230         test_check_ignore "-z" 128 &&
231         stderr_contains "fatal: -z only makes sense with --stdin"
232 '
233
234 test_expect_success_multi '-z without --stdin and superfluous arg' '' '
235         test_check_ignore "-z foo" 128 &&
236         stderr_contains "fatal: -z only makes sense with --stdin"
237 '
238
239 test_expect_success_multi 'needs work tree' '' '
240         (
241                 cd .git &&
242                 test_check_ignore "foo" 128
243         ) &&
244         stderr_contains "fatal: This operation must be run in a work tree"
245 '
246
247 ############################################################################
248 #
249 # test standard ignores
250
251 # First make sure that the presence of a file in the working tree
252 # does not impact results, but that the presence of a file in the
253 # index does.
254
255 for subdir in '' 'a/'
256 do
257         if test -z "$subdir"
258         then
259                 where="at top-level"
260         else
261                 where="in subdir $subdir"
262         fi
263
264         test_expect_success_multi "non-existent file $where not ignored" '' "
265                 test_check_ignore '${subdir}non-existent' 1
266         "
267
268         test_expect_success_multi "non-existent file $where ignored" \
269                 ".gitignore:1:one       ${subdir}one" "
270                 test_check_ignore '${subdir}one'
271         "
272
273         test_expect_success_multi "existing untracked file $where not ignored" '' "
274                 test_check_ignore '${subdir}not-ignored' 1
275         "
276
277         test_expect_success_multi "existing tracked file $where not ignored" '' "
278                 test_check_ignore '${subdir}ignored-but-in-index' 1
279         "
280
281         test_expect_success_multi "existing untracked file $where ignored" \
282                 ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" "
283                 test_check_ignore '${subdir}ignored-and-untracked'
284         "
285 done
286
287 # Having established the above, from now on we mostly test against
288 # files which do not exist in the working tree or index.
289
290 test_expect_success 'sub-directory local ignore' '
291         expect "a/3-three" &&
292         test_check_ignore "a/3-three a/three-not-this-one"
293 '
294
295 test_expect_success 'sub-directory local ignore with --verbose'  '
296         expect "a/.gitignore:2:*three   a/3-three" &&
297         test_check_ignore "--verbose a/3-three a/three-not-this-one"
298 '
299
300 test_expect_success 'local ignore inside a sub-directory' '
301         expect "3-three" &&
302         (
303                 cd a &&
304                 test_check_ignore "3-three three-not-this-one"
305         )
306 '
307 test_expect_success 'local ignore inside a sub-directory with --verbose' '
308         expect "a/.gitignore:2:*three   3-three" &&
309         (
310                 cd a &&
311                 test_check_ignore "--verbose 3-three three-not-this-one"
312         )
313 '
314
315 test_expect_success_multi 'nested include' \
316         'a/b/.gitignore:8:!on*  a/b/one' '
317         test_check_ignore "a/b/one"
318 '
319
320 ############################################################################
321 #
322 # test ignored sub-directories
323
324 test_expect_success_multi 'ignored sub-directory' \
325         'a/b/.gitignore:5:ignored-dir/  a/b/ignored-dir' '
326         test_check_ignore "a/b/ignored-dir"
327 '
328
329 test_expect_success 'multiple files inside ignored sub-directory' '
330         expect_from_stdin <<-\EOF &&
331                 a/b/ignored-dir/foo
332                 a/b/ignored-dir/twoooo
333                 a/b/ignored-dir/seven
334         EOF
335         test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
336 '
337
338 test_expect_success 'multiple files inside ignored sub-directory with -v' '
339         expect_from_stdin <<-\EOF &&
340                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/foo
341                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/twoooo
342                 a/b/.gitignore:5:ignored-dir/   a/b/ignored-dir/seven
343         EOF
344         test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
345 '
346
347 test_expect_success 'cd to ignored sub-directory' '
348         expect_from_stdin <<-\EOF &&
349                 foo
350                 twoooo
351                 ../one
352                 seven
353                 ../../one
354         EOF
355         (
356                 cd a/b/ignored-dir &&
357                 test_check_ignore "foo twoooo ../one seven ../../one"
358         )
359 '
360
361 test_expect_success 'cd to ignored sub-directory with -v' '
362         expect_from_stdin <<-\EOF &&
363                 a/b/.gitignore:5:ignored-dir/   foo
364                 a/b/.gitignore:5:ignored-dir/   twoooo
365                 a/b/.gitignore:8:!on*   ../one
366                 a/b/.gitignore:5:ignored-dir/   seven
367                 .gitignore:1:one        ../../one
368         EOF
369         (
370                 cd a/b/ignored-dir &&
371                 test_check_ignore "-v foo twoooo ../one seven ../../one"
372         )
373 '
374
375 ############################################################################
376 #
377 # test handling of symlinks
378
379 test_expect_success_multi SYMLINKS 'symlink' '' '
380         test_check_ignore "a/symlink" 1
381 '
382
383 test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
384         test_check_ignore "a/symlink/foo" 128 &&
385         test_stderr "fatal: '\''a/symlink/foo'\'' is beyond a symbolic link"
386 '
387
388 test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
389         (
390                 cd a &&
391                 test_check_ignore "symlink/foo" 128
392         ) &&
393         test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
394 '
395
396 ############################################################################
397 #
398 # test handling of submodules
399
400 test_expect_success_multi 'submodule' '' '
401         test_check_ignore "a/submodule/one" 128 &&
402         test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
403 '
404
405 test_expect_success_multi 'submodule from subdirectory' '' '
406         (
407                 cd a &&
408                 test_check_ignore "submodule/one" 128
409         ) &&
410         test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
411 '
412
413 ############################################################################
414 #
415 # test handling of global ignore files
416
417 test_expect_success 'global ignore not yet enabled' '
418         expect_from_stdin <<-\EOF &&
419                 .git/info/exclude:7:per-repo    per-repo
420                 a/.gitignore:2:*three   a/globalthree
421                 .git/info/exclude:7:per-repo    a/per-repo
422         EOF
423         test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
424 '
425
426 test_expect_success 'global ignore' '
427         enable_global_excludes &&
428         expect_from_stdin <<-\EOF &&
429                 globalone
430                 per-repo
431                 globalthree
432                 a/globalthree
433                 a/per-repo
434                 globaltwo
435         EOF
436         test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
437 '
438
439 test_expect_success 'global ignore with -v' '
440         enable_global_excludes &&
441         expect_from_stdin <<-EOF &&
442                 $global_excludes:1:globalone    globalone
443                 .git/info/exclude:7:per-repo    per-repo
444                 $global_excludes:3:globalthree  globalthree
445                 a/.gitignore:2:*three   a/globalthree
446                 .git/info/exclude:7:per-repo    a/per-repo
447                 $global_excludes:2:!globaltwo   globaltwo
448         EOF
449         test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
450 '
451
452 ############################################################################
453 #
454 # test --stdin
455
456 cat <<-\EOF >stdin
457         one
458         not-ignored
459         a/one
460         a/not-ignored
461         a/b/on
462         a/b/one
463         a/b/one one
464         "a/b/one two"
465         "a/b/one\"three"
466         a/b/not-ignored
467         a/b/two
468         a/b/twooo
469         globaltwo
470         a/globaltwo
471         a/b/globaltwo
472         b/globaltwo
473 EOF
474 cat <<-\EOF >expected-default
475         one
476         a/one
477         a/b/on
478         a/b/one
479         a/b/one one
480         a/b/one two
481         "a/b/one\"three"
482         a/b/two
483         a/b/twooo
484         globaltwo
485         a/globaltwo
486         a/b/globaltwo
487         b/globaltwo
488 EOF
489 cat <<-EOF >expected-verbose
490         .gitignore:1:one        one
491         .gitignore:1:one        a/one
492         a/b/.gitignore:8:!on*   a/b/on
493         a/b/.gitignore:8:!on*   a/b/one
494         a/b/.gitignore:8:!on*   a/b/one one
495         a/b/.gitignore:8:!on*   a/b/one two
496         a/b/.gitignore:8:!on*   "a/b/one\"three"
497         a/b/.gitignore:9:!two   a/b/two
498         a/.gitignore:1:two*     a/b/twooo
499         $global_excludes:2:!globaltwo   globaltwo
500         $global_excludes:2:!globaltwo   a/globaltwo
501         $global_excludes:2:!globaltwo   a/b/globaltwo
502         $global_excludes:2:!globaltwo   b/globaltwo
503 EOF
504
505 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
506         tr "\n" "\0" >stdin0
507 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
508         tr "\n" "\0" >expected-default0
509 sed -e 's/      "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
510         tr ":\t\n" "\0" >expected-verbose0
511
512 test_expect_success '--stdin' '
513         expect_from_stdin <expected-default &&
514         test_check_ignore "--stdin" <stdin
515 '
516
517 test_expect_success '--stdin -q' '
518         expect "" &&
519         test_check_ignore "-q --stdin" <stdin
520 '
521
522 test_expect_success '--stdin -v' '
523         expect_from_stdin <expected-verbose &&
524         test_check_ignore "-v --stdin" <stdin
525 '
526
527 for opts in '--stdin -z' '-z --stdin'
528 do
529         test_expect_success "$opts" "
530                 expect_from_stdin <expected-default0 &&
531                 test_check_ignore '$opts' <stdin0
532         "
533
534         test_expect_success "$opts -q" "
535                 expect "" &&
536                 test_check_ignore '-q $opts' <stdin0
537         "
538
539         test_expect_success "$opts -v" "
540                 expect_from_stdin <expected-verbose0 &&
541                 test_check_ignore '-v $opts' <stdin0
542         "
543 done
544
545 cat <<-\EOF >stdin
546         ../one
547         ../not-ignored
548         one
549         not-ignored
550         b/on
551         b/one
552         b/one one
553         "b/one two"
554         "b/one\"three"
555         b/two
556         b/not-ignored
557         b/twooo
558         ../globaltwo
559         globaltwo
560         b/globaltwo
561         ../b/globaltwo
562 EOF
563 cat <<-\EOF >expected-default
564         ../one
565         one
566         b/on
567         b/one
568         b/one one
569         b/one two
570         "b/one\"three"
571         b/two
572         b/twooo
573         ../globaltwo
574         globaltwo
575         b/globaltwo
576         ../b/globaltwo
577 EOF
578 cat <<-EOF >expected-verbose
579         .gitignore:1:one        ../one
580         .gitignore:1:one        one
581         a/b/.gitignore:8:!on*   b/on
582         a/b/.gitignore:8:!on*   b/one
583         a/b/.gitignore:8:!on*   b/one one
584         a/b/.gitignore:8:!on*   b/one two
585         a/b/.gitignore:8:!on*   "b/one\"three"
586         a/b/.gitignore:9:!two   b/two
587         a/.gitignore:1:two*     b/twooo
588         $global_excludes:2:!globaltwo   ../globaltwo
589         $global_excludes:2:!globaltwo   globaltwo
590         $global_excludes:2:!globaltwo   b/globaltwo
591         $global_excludes:2:!globaltwo   ../b/globaltwo
592 EOF
593
594 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
595         tr "\n" "\0" >stdin0
596 sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
597         tr "\n" "\0" >expected-default0
598 sed -e 's/      "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
599         tr ":\t\n" "\0" >expected-verbose0
600
601 test_expect_success '--stdin from subdirectory' '
602         expect_from_stdin <expected-default &&
603         (
604                 cd a &&
605                 test_check_ignore "--stdin" <../stdin
606         )
607 '
608
609 test_expect_success '--stdin from subdirectory with -v' '
610         expect_from_stdin <expected-verbose &&
611         (
612                 cd a &&
613                 test_check_ignore "--stdin -v" <../stdin
614         )
615 '
616
617 for opts in '--stdin -z' '-z --stdin'
618 do
619         test_expect_success "$opts from subdirectory" '
620                 expect_from_stdin <expected-default0 &&
621                 (
622                         cd a &&
623                         test_check_ignore "'"$opts"'" <../stdin0
624                 )
625         '
626
627         test_expect_success "$opts from subdirectory with -v" '
628                 expect_from_stdin <expected-verbose0 &&
629                 (
630                         cd a &&
631                         test_check_ignore "'"$opts"' -v" <../stdin0
632                 )
633         '
634 done
635
636
637 test_done