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