]>
Commit | Line | Data |
---|---|---|
368aa529 AS |
1 | #!/bin/sh |
2 | ||
3 | test_description=check-ignore | |
4 | ||
c150064d | 5 | TEST_PASSES_SANITIZE_LEAK=true |
1d758728 | 6 | TEST_CREATE_REPO_NO_TEMPLATE=1 |
368aa529 AS |
7 | . ./test-lib.sh |
8 | ||
9 | init_vars () { | |
2b3abd45 | 10 | global_excludes="global-excludes" |
368aa529 AS |
11 | } |
12 | ||
13 | enable_global_excludes () { | |
14 | init_vars && | |
15 | git config core.excludesfile "$global_excludes" | |
16 | } | |
17 | ||
18 | expect_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 | ||
28 | expect () { | |
29 | expect_in stdout "$1" | |
30 | } | |
31 | ||
32 | expect_from_stdin () { | |
33 | cat >"$HOME/expected-stdout" | |
34 | } | |
35 | ||
36 | test_stderr () { | |
37 | expected="$1" | |
38 | expect_in stderr "$1" && | |
1108cea7 | 39 | test_cmp "$HOME/expected-stderr" "$HOME/stderr" |
368aa529 AS |
40 | } |
41 | ||
53039ab1 BW |
42 | broken_c_unquote () { |
43 | "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@" | |
44 | } | |
45 | ||
46 | broken_c_unquote_verbose () { | |
47 | "$PERL_PATH" -pe 's/ "/ /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@" | |
48 | } | |
49 | ||
368aa529 AS |
50 | stderr_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 | ||
62 | stderr_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 | ||
74 | test_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 |
111 | test_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 | ||
172 | test_expect_success_multi () { | |
173 | test_expect_success_multiple "$@" "--index" | |
174 | } | |
175 | ||
176 | test_expect_success_no_index_multi () { | |
177 | test_expect_success_multiple "$@" "--no-index" | |
368aa529 AS |
178 | } |
179 | ||
180 | test_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 | 239 | test_expect_success_multi '. corner-case' ':: .' ' |
c19387e7 JH |
240 | test_check_ignore . 1 |
241 | ' | |
242 | ||
368aa529 AS |
243 | test_expect_success_multi 'empty command line' '' ' |
244 | test_check_ignore "" 128 && | |
245 | stderr_contains "fatal: no path specified" | |
246 | ' | |
247 | ||
248 | test_expect_success_multi '--stdin with empty STDIN' '' ' | |
249 | test_check_ignore "--stdin" 1 </dev/null && | |
0c8e8c08 | 250 | test_stderr "" |
368aa529 AS |
251 | ' |
252 | ||
253 | test_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 | ||
259 | test_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 | ||
265 | for verbose_opt in '-v' '--verbose' | |
266 | do | |
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 | |
275 | done | |
276 | ||
277 | test_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 | ||
283 | test_expect_success_multi 'erroneous use of --' '' ' | |
284 | test_check_ignore "--" 128 && | |
285 | stderr_contains "fatal: no path specified" | |
286 | ' | |
287 | ||
288 | test_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 | ||
293 | test_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 | ||
298 | test_expect_success_multi '-z without --stdin' '' ' | |
299 | test_check_ignore "-z" 128 && | |
300 | stderr_contains "fatal: -z only makes sense with --stdin" | |
301 | ' | |
302 | ||
303 | test_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 | ||
308 | test_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 | |
324 | for subdir in '' 'a/' | |
325 | do | |
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 |
400 | done |
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 | ||
405 | test_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 | ||
410 | test_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 | ||
415 | test_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 | ' | |
422 | test_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 |
430 | test_expect_success 'nested include of negated pattern' ' |
431 | expect "" && | |
432 | test_check_ignore "a/b/one" 1 | |
433 | ' | |
434 | ||
435 | test_expect_success 'nested include of negated pattern with -q' ' | |
436 | expect "" && | |
437 | test_check_ignore "-q a/b/one" 1 | |
438 | ' | |
439 | ||
440 | test_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 | ||
445 | test_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 | ||
454 | test_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 | ||
459 | test_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 | ||
468 | test_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 | ||
477 | test_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 | ||
490 | test_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 | 508 | test_expect_success_multi SYMLINKS 'symlink' ':: a/symlink' ' |
368aa529 AS |
509 | test_check_ignore "a/symlink" 1 |
510 | ' | |
511 | ||
512 | test_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 | ||
517 | test_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 | ||
529 | test_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 | ||
534 | test_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 | ||
546 | test_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 | ||
555 | test_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 | ||
567 | test_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 | ||
584 | cat <<-\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 | |
601 | EOF | |
602 | cat <<-\EOF >expected-default | |
603 | one | |
604 | a/one | |
368aa529 | 605 | a/b/twooo |
368aa529 AS |
606 | EOF |
607 | cat <<-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 | |
621 | EOF | |
622 | ||
53039ab1 BW |
623 | broken_c_unquote stdin >stdin0 |
624 | ||
625 | broken_c_unquote expected-default >expected-default0 | |
626 | ||
627 | broken_c_unquote_verbose expected-verbose >expected-verbose0 | |
368aa529 AS |
628 | |
629 | test_expect_success '--stdin' ' | |
630 | expect_from_stdin <expected-default && | |
631 | test_check_ignore "--stdin" <stdin | |
632 | ' | |
633 | ||
634 | test_expect_success '--stdin -q' ' | |
635 | expect "" && | |
636 | test_check_ignore "-q --stdin" <stdin | |
637 | ' | |
638 | ||
639 | test_expect_success '--stdin -v' ' | |
640 | expect_from_stdin <expected-verbose && | |
641 | test_check_ignore "-v --stdin" <stdin | |
642 | ' | |
643 | ||
644 | for opts in '--stdin -z' '-z --stdin' | |
645 | do | |
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 | " | |
660 | done | |
661 | ||
662 | cat <<-\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 | 680 | EOF |
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 | ||
686 | cat <<-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 | 704 | EOF |
7ec8125f EN |
705 | cat <<-EOF >expected-default |
706 | ../one | |
707 | one | |
708 | b/twooo | |
709 | EOF | |
ae3caf4c | 710 | grep -v '^:: ' expected-all >expected-verbose |
368aa529 | 711 | |
53039ab1 BW |
712 | broken_c_unquote stdin >stdin0 |
713 | ||
714 | broken_c_unquote expected-default >expected-default0 | |
715 | ||
716 | broken_c_unquote_verbose expected-verbose >expected-verbose0 | |
368aa529 AS |
717 | |
718 | test_expect_success '--stdin from subdirectory' ' | |
719 | expect_from_stdin <expected-default && | |
720 | ( | |
721 | cd a && | |
722 | test_check_ignore "--stdin" <../stdin | |
723 | ) | |
724 | ' | |
725 | ||
726 | test_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 |
734 | test_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 |
742 | for opts in '--stdin -z' '-z --stdin' |
743 | do | |
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 | ' | |
759 | done | |
760 | ||
b96114ed AS |
761 | test_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 |
788 | test_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 | ||
798 | test_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 |
808 | test_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 | ||
821 | test_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 |
834 | test_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 | 855 | test_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 |
861 | whitespace/untracked |
862 | EOF | |
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 | 868 | test_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 | 880 | test_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 |
904 | test_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 |
914 | test_expect_success SYMLINKS 'set up ignore file for symlink tests' ' |
915 | echo "*" >ignore && | |
916 | rm -f .gitignore .git/info/exclude | |
917 | ' | |
918 | ||
919 | test_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 | ||
929 | test_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 | ||
938 | test_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 | 948 | test_done |