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