]>
Commit | Line | Data |
---|---|---|
60ace879 CW |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2006 Carl D. Worth | |
4 | # | |
5 | ||
5be60078 | 6 | test_description='Test of git add, including the -- option.' |
60ace879 | 7 | |
eab4ac6a | 8 | TEST_PASSES_SANITIZE_LEAK=true |
60ace879 CW |
9 | . ./test-lib.sh |
10 | ||
766cdc41 IB |
11 | # Test the file mode "$1" of the file "$2" in the index. |
12 | test_mode_in_index () { | |
13 | case "$(git ls-files -s "$2")" in | |
14 | "$1 "*" $2") | |
15 | echo pass | |
16 | ;; | |
17 | *) | |
18 | echo fail | |
19 | git ls-files -s "$2" | |
20 | return 1 | |
21 | ;; | |
22 | esac | |
23 | } | |
24 | ||
60ace879 | 25 | test_expect_success \ |
5be60078 JH |
26 | 'Test of git add' \ |
27 | 'touch foo && git add foo' | |
60ace879 CW |
28 | |
29 | test_expect_success \ | |
30 | 'Post-check that foo is in the index' \ | |
5be60078 | 31 | 'git ls-files foo | grep foo' |
60ace879 CW |
32 | |
33 | test_expect_success \ | |
5be60078 JH |
34 | 'Test that "git add -- -q" works' \ |
35 | 'touch -- -q && git add -- -q' | |
60ace879 | 36 | |
fd28b34a | 37 | test_expect_success \ |
5be60078 | 38 | 'git add: Test that executable bit is not used if core.filemode=0' \ |
e0d10e1c | 39 | 'git config core.filemode 0 && |
fd28b34a SP |
40 | echo foo >xfoo1 && |
41 | chmod 755 xfoo1 && | |
5be60078 | 42 | git add xfoo1 && |
766cdc41 | 43 | test_mode_in_index 100644 xfoo1' |
fd28b34a | 44 | |
889c6f0e | 45 | test_expect_success 'git add: filemode=0 should not get confused by symlink' ' |
185c975f | 46 | rm -f xfoo1 && |
889c6f0e | 47 | test_ln_s_add foo xfoo1 && |
766cdc41 | 48 | test_mode_in_index 120000 xfoo1 |
185c975f JH |
49 | ' |
50 | ||
fd28b34a | 51 | test_expect_success \ |
5be60078 | 52 | 'git update-index --add: Test that executable bit is not used...' \ |
e0d10e1c | 53 | 'git config core.filemode 0 && |
fd28b34a SP |
54 | echo foo >xfoo2 && |
55 | chmod 755 xfoo2 && | |
5be60078 | 56 | git update-index --add xfoo2 && |
766cdc41 | 57 | test_mode_in_index 100644 xfoo2' |
2bbaaed9 | 58 | |
889c6f0e | 59 | test_expect_success 'git add: filemode=0 should not get confused by symlink' ' |
185c975f | 60 | rm -f xfoo2 && |
889c6f0e | 61 | test_ln_s_add foo xfoo2 && |
766cdc41 | 62 | test_mode_in_index 120000 xfoo2 |
185c975f JH |
63 | ' |
64 | ||
889c6f0e | 65 | test_expect_success \ |
5be60078 | 66 | 'git update-index --add: Test that executable bit is not used...' \ |
e0d10e1c | 67 | 'git config core.filemode 0 && |
889c6f0e | 68 | test_ln_s_add xfoo2 xfoo3 && # runs git update-index --add |
766cdc41 | 69 | test_mode_in_index 120000 xfoo3' |
fd28b34a | 70 | |
4d06f8ac JH |
71 | test_expect_success '.gitignore test setup' ' |
72 | echo "*.ig" >.gitignore && | |
73 | mkdir c.if d.ig && | |
74 | >a.ig && >b.if && | |
75 | >c.if/c.if && >c.if/c.ig && | |
76 | >d.ig/d.if && >d.ig/d.ig | |
77 | ' | |
78 | ||
79 | test_expect_success '.gitignore is honored' ' | |
5be60078 | 80 | git add . && |
bbf08124 | 81 | ! (git ls-files | grep "\\.ig") |
4d06f8ac JH |
82 | ' |
83 | ||
84 | test_expect_success 'error out when attempting to add ignored ones without -f' ' | |
d492b31c | 85 | test_must_fail git add a.?? && |
bbf08124 | 86 | ! (git ls-files | grep "\\.ig") |
4d06f8ac JH |
87 | ' |
88 | ||
89 | test_expect_success 'error out when attempting to add ignored ones without -f' ' | |
d492b31c | 90 | test_must_fail git add d.?? && |
bbf08124 | 91 | ! (git ls-files | grep "\\.ig") |
4d06f8ac JH |
92 | ' |
93 | ||
1d31e5a2 MG |
94 | test_expect_success 'error out when attempting to add ignored ones but add others' ' |
95 | touch a.if && | |
96 | test_must_fail git add a.?? && | |
97 | ! (git ls-files | grep "\\.ig") && | |
98 | (git ls-files | grep a.if) | |
99 | ' | |
100 | ||
4d06f8ac | 101 | test_expect_success 'add ignored ones with -f' ' |
5be60078 JH |
102 | git add -f a.?? && |
103 | git ls-files --error-unmatch a.ig | |
4d06f8ac JH |
104 | ' |
105 | ||
106 | test_expect_success 'add ignored ones with -f' ' | |
5be60078 JH |
107 | git add -f d.??/* && |
108 | git ls-files --error-unmatch d.ig/d.if d.ig/d.ig | |
4d06f8ac JH |
109 | ' |
110 | ||
41a7aa58 JH |
111 | test_expect_success 'add ignored ones with -f' ' |
112 | rm -f .git/index && | |
113 | git add -f d.?? && | |
114 | git ls-files --error-unmatch d.ig/d.if d.ig/d.ig | |
115 | ' | |
116 | ||
117 | test_expect_success '.gitignore with subdirectory' ' | |
118 | ||
119 | rm -f .git/index && | |
120 | mkdir -p sub/dir && | |
121 | echo "!dir/a.*" >sub/.gitignore && | |
122 | >sub/a.ig && | |
123 | >sub/dir/a.ig && | |
124 | git add sub/dir && | |
125 | git ls-files --error-unmatch sub/dir/a.ig && | |
126 | rm -f .git/index && | |
127 | ( | |
128 | cd sub/dir && | |
129 | git add . | |
130 | ) && | |
131 | git ls-files --error-unmatch sub/dir/a.ig | |
132 | ' | |
133 | ||
c7f34c18 JS |
134 | mkdir 1 1/2 1/3 |
135 | touch 1/2/a 1/3/b 1/2/c | |
136 | test_expect_success 'check correct prefix detection' ' | |
41a7aa58 | 137 | rm -f .git/index && |
c7f34c18 JS |
138 | git add 1/2/a 1/3/b 1/2/c |
139 | ' | |
140 | ||
05dcd698 | 141 | test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' ' |
20314271 JS |
142 | for s in 1 2 3 |
143 | do | |
74d2f569 ES |
144 | echo $s > stage$s && |
145 | echo "100755 $(git hash-object -w stage$s) $s file" && | |
05dcd698 | 146 | echo "120000 $(printf $s | git hash-object -w -t blob --stdin) $s symlink" |
20314271 JS |
147 | done | git update-index --index-info && |
148 | git config core.filemode 0 && | |
05dcd698 | 149 | git config core.symlinks 0 && |
20314271 | 150 | echo new > file && |
05dcd698 JS |
151 | echo new > symlink && |
152 | git add file symlink && | |
153 | git ls-files --stage | grep "^100755 .* 0 file$" && | |
154 | git ls-files --stage | grep "^120000 .* 0 symlink$" | |
20314271 JS |
155 | ' |
156 | ||
05dcd698 JS |
157 | test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' ' |
158 | git rm --cached -f file symlink && | |
20314271 | 159 | ( |
3ea67379 ES |
160 | echo "100644 $(git hash-object -w stage1) 1 file" && |
161 | echo "100755 $(git hash-object -w stage2) 2 file" && | |
162 | echo "100644 $(printf 1 | git hash-object -w -t blob --stdin) 1 symlink" && | |
a697ec69 | 163 | echo "120000 $(printf 2 | git hash-object -w -t blob --stdin) 2 symlink" |
20314271 JS |
164 | ) | git update-index --index-info && |
165 | git config core.filemode 0 && | |
05dcd698 | 166 | git config core.symlinks 0 && |
20314271 | 167 | echo new > file && |
05dcd698 JS |
168 | echo new > symlink && |
169 | git add file symlink && | |
170 | git ls-files --stage | grep "^100755 .* 0 file$" && | |
171 | git ls-files --stage | grep "^120000 .* 0 symlink$" | |
20314271 JS |
172 | ' |
173 | ||
d616813d AJ |
174 | test_expect_success 'git add --refresh' ' |
175 | >foo && git add foo && git commit -a -m "commit all" && | |
ed6c2314 | 176 | test -z "$(git diff-index HEAD -- foo)" && |
d616813d | 177 | git read-tree HEAD && |
ed6c2314 | 178 | case "$(git diff-index HEAD -- foo)" in |
335f8787 | 179 | :100644" "*"M foo") echo pass;; |
77b1d9f3 | 180 | *) echo fail; false;; |
d616813d AJ |
181 | esac && |
182 | git add --refresh -- foo && | |
ed6c2314 | 183 | test -z "$(git diff-index HEAD -- foo)" |
d616813d AJ |
184 | ' |
185 | ||
3d1f148c JH |
186 | test_expect_success 'git add --refresh with pathspec' ' |
187 | git reset --hard && | |
188 | echo >foo && echo >bar && echo >baz && | |
189 | git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo && | |
190 | echo "100644 $H 3 foo" | git update-index --index-info && | |
0e496492 | 191 | test-tool chmtime -60 bar baz && |
3d1f148c | 192 | git add --refresh bar >actual && |
d3c6751b | 193 | test_must_be_empty actual && |
3d1f148c JH |
194 | |
195 | git diff-files --name-only >actual && | |
64d1022e | 196 | ! grep bar actual && |
3d1f148c JH |
197 | grep baz actual |
198 | ' | |
199 | ||
4e956983 MT |
200 | test_expect_success 'git add --refresh correctly reports no match error' " |
201 | echo \"fatal: pathspec ':(icase)nonexistent' did not match any files\" >expect && | |
202 | test_must_fail git add --refresh ':(icase)nonexistent' 2>actual && | |
203 | test_cmp expect actual | |
204 | " | |
205 | ||
c91cfd19 | 206 | test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' ' |
89597436 AR |
207 | git reset --hard && |
208 | date >foo1 && | |
209 | date >foo2 && | |
210 | chmod 0 foo2 && | |
211 | test_must_fail git add --verbose . && | |
212 | ! ( git ls-files foo1 | grep foo1 ) | |
213 | ' | |
214 | ||
215 | rm -f foo2 | |
216 | ||
c91cfd19 | 217 | test_expect_success POSIXPERM,SANITY 'git add --ignore-errors' ' |
89597436 AR |
218 | git reset --hard && |
219 | date >foo1 && | |
220 | date >foo2 && | |
221 | chmod 0 foo2 && | |
222 | test_must_fail git add --verbose --ignore-errors . && | |
223 | git ls-files foo1 | grep foo1 | |
224 | ' | |
225 | ||
226 | rm -f foo2 | |
227 | ||
c91cfd19 | 228 | test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors)' ' |
dad25e4a AR |
229 | git config add.ignore-errors 1 && |
230 | git reset --hard && | |
231 | date >foo1 && | |
232 | date >foo2 && | |
233 | chmod 0 foo2 && | |
234 | test_must_fail git add --verbose . && | |
235 | git ls-files foo1 | grep foo1 | |
236 | ' | |
237 | rm -f foo2 | |
238 | ||
c91cfd19 | 239 | test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors = false)' ' |
dad25e4a AR |
240 | git config add.ignore-errors 0 && |
241 | git reset --hard && | |
242 | date >foo1 && | |
243 | date >foo2 && | |
244 | chmod 0 foo2 && | |
245 | test_must_fail git add --verbose . && | |
246 | ! ( git ls-files foo1 | grep foo1 ) | |
247 | ' | |
ed342fde SB |
248 | rm -f foo2 |
249 | ||
c91cfd19 | 250 | test_expect_success POSIXPERM,SANITY '--no-ignore-errors overrides config' ' |
ed342fde SB |
251 | git config add.ignore-errors 1 && |
252 | git reset --hard && | |
253 | date >foo1 && | |
254 | date >foo2 && | |
255 | chmod 0 foo2 && | |
256 | test_must_fail git add --verbose --no-ignore-errors . && | |
257 | ! ( git ls-files foo1 | grep foo1 ) && | |
258 | git config add.ignore-errors 0 | |
259 | ' | |
260 | rm -f foo2 | |
dad25e4a | 261 | |
6fd1106a | 262 | test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" ' |
ea335b56 | 263 | git reset --hard && |
8134a003 AR |
264 | touch fo\[ou\]bar foobar && |
265 | git add '\''fo\[ou\]bar'\'' && | |
87539416 | 266 | git ls-files fo\[ou\]bar | fgrep fo\[ou\]bar && |
ea335b56 KB |
267 | ! ( git ls-files foobar | grep foobar ) |
268 | ' | |
269 | ||
6e4f981f JK |
270 | test_expect_success 'git add to resolve conflicts on otherwise ignored path' ' |
271 | git reset --hard && | |
272 | H=$(git rev-parse :1/2/a) && | |
273 | ( | |
3ea67379 | 274 | echo "100644 $H 1 track-this" && |
6e4f981f JK |
275 | echo "100644 $H 3 track-this" |
276 | ) | git update-index --index-info && | |
277 | echo track-this >>.gitignore && | |
278 | echo resolved >track-this && | |
279 | git add track-this | |
280 | ' | |
281 | ||
1e7ef746 CP |
282 | test_expect_success '"add non-existent" should fail' ' |
283 | test_must_fail git add non-existent && | |
284 | ! (git ls-files | grep "non-existent") | |
285 | ' | |
286 | ||
64ed07ce NTND |
287 | test_expect_success 'git add -A on empty repo does not error out' ' |
288 | rm -fr empty && | |
289 | git init empty && | |
290 | ( | |
291 | cd empty && | |
292 | git add -A . && | |
293 | git add -A | |
294 | ) | |
295 | ' | |
296 | ||
297 | test_expect_success '"git add ." in empty repo' ' | |
298 | rm -fr empty && | |
299 | git init empty && | |
300 | ( | |
301 | cd empty && | |
302 | git add . | |
303 | ) | |
304 | ' | |
305 | ||
f937bc2f KM |
306 | test_expect_success 'error on a repository with no commits' ' |
307 | rm -fr empty && | |
308 | git init empty && | |
309 | test_must_fail git add empty >actual 2>&1 && | |
310 | cat >expect <<-EOF && | |
311 | error: '"'empty/'"' does not have a commit checked out | |
312 | fatal: adding files failed | |
313 | EOF | |
1108cea7 | 314 | test_cmp expect actual |
f937bc2f KM |
315 | ' |
316 | ||
108da0db JL |
317 | test_expect_success 'git add --dry-run of existing changed file' " |
318 | echo new >>track-this && | |
319 | git add --dry-run track-this >actual 2>&1 && | |
320 | echo \"add 'track-this'\" | test_cmp - actual | |
321 | " | |
322 | ||
323 | test_expect_success 'git add --dry-run of non-existing file' " | |
324 | echo ignored-file >>.gitignore && | |
48168851 ÆAB |
325 | test_must_fail git add --dry-run track-this ignored-file >actual 2>&1 |
326 | " | |
327 | ||
68b2a005 | 328 | test_expect_success 'git add --dry-run of an existing file output' " |
48168851 | 329 | echo \"fatal: pathspec 'ignored-file' did not match any files\" >expect && |
1108cea7 | 330 | test_cmp expect actual |
108da0db JL |
331 | " |
332 | ||
c1e02b2b | 333 | cat >expect.err <<\EOF |
108da0db JL |
334 | The following paths are ignored by one of your .gitignore files: |
335 | ignored-file | |
bf66db37 | 336 | hint: Use -f if you really want to add them. |
887a0fd5 HW |
337 | hint: Turn this message off by running |
338 | hint: "git config advice.addIgnoredFile false" | |
c1e02b2b JS |
339 | EOF |
340 | cat >expect.out <<\EOF | |
108da0db JL |
341 | add 'track-this' |
342 | EOF | |
343 | ||
344 | test_expect_success 'git add --dry-run --ignore-missing of non-existing file' ' | |
439fb829 ÆAB |
345 | test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err |
346 | ' | |
347 | ||
68b2a005 | 348 | test_expect_success 'git add --dry-run --ignore-missing of non-existing file output' ' |
1108cea7 ÆAB |
349 | test_cmp expect.out actual.out && |
350 | test_cmp expect.err actual.err | |
108da0db JL |
351 | ' |
352 | ||
a1989cf7 ØW |
353 | test_expect_success 'git add --dry-run --interactive should fail' ' |
354 | test_must_fail git add --dry-run --interactive | |
355 | ' | |
356 | ||
9e4e8a64 EX |
357 | test_expect_success 'git add empty string should fail' ' |
358 | test_must_fail git add "" | |
d426430e EX |
359 | ' |
360 | ||
b38ab197 | 361 | test_expect_success 'git add --chmod=[+-]x stages correctly' ' |
c0fa44d8 | 362 | rm -f foo1 && |
4e55ed32 ET |
363 | echo foo >foo1 && |
364 | git add --chmod=+x foo1 && | |
766cdc41 | 365 | test_mode_in_index 100755 foo1 && |
b38ab197 | 366 | git add --chmod=-x foo1 && |
766cdc41 | 367 | test_mode_in_index 100644 foo1 |
4e55ed32 ET |
368 | ' |
369 | ||
370 | test_expect_success POSIXPERM,SYMLINKS 'git add --chmod=+x with symlinks' ' | |
371 | git config core.filemode 1 && | |
372 | git config core.symlinks 1 && | |
c0fa44d8 | 373 | rm -f foo2 && |
4e55ed32 ET |
374 | echo foo >foo2 && |
375 | git add --chmod=+x foo2 && | |
766cdc41 | 376 | test_mode_in_index 100755 foo2 |
4e55ed32 ET |
377 | ' |
378 | ||
610d55af | 379 | test_expect_success 'git add --chmod=[+-]x changes index with already added file' ' |
76e368c3 | 380 | rm -f foo3 xfoo3 && |
57ea241e | 381 | git reset --hard && |
610d55af TG |
382 | echo foo >foo3 && |
383 | git add foo3 && | |
384 | git add --chmod=+x foo3 && | |
385 | test_mode_in_index 100755 foo3 && | |
386 | echo foo >xfoo3 && | |
387 | chmod 755 xfoo3 && | |
388 | git add xfoo3 && | |
389 | git add --chmod=-x xfoo3 && | |
390 | test_mode_in_index 100644 xfoo3 | |
391 | ' | |
392 | ||
40e0dc17 | 393 | test_expect_success POSIXPERM 'git add --chmod=[+-]x does not change the working tree' ' |
610d55af TG |
394 | echo foo >foo4 && |
395 | git add foo4 && | |
396 | git add --chmod=+x foo4 && | |
40e0dc17 | 397 | ! test -x foo4 |
610d55af TG |
398 | ' |
399 | ||
9ebd7fe1 MT |
400 | test_expect_success 'git add --chmod fails with non regular files (but updates the other paths)' ' |
401 | git reset --hard && | |
402 | test_ln_s_add foo foo3 && | |
403 | touch foo4 && | |
404 | test_must_fail git add --chmod=+x foo3 foo4 2>stderr && | |
405 | test_i18ngrep "cannot chmod +x .foo3." stderr && | |
406 | test_mode_in_index 120000 foo3 && | |
407 | test_mode_in_index 100755 foo4 | |
408 | ' | |
409 | ||
c937d70b MT |
410 | test_expect_success 'git add --chmod honors --dry-run' ' |
411 | git reset --hard && | |
412 | echo foo >foo4 && | |
413 | git add foo4 && | |
414 | git add --chmod=+x --dry-run foo4 && | |
415 | test_mode_in_index 100644 foo4 | |
416 | ' | |
417 | ||
418 | test_expect_success 'git add --chmod --dry-run reports error for non regular files' ' | |
419 | git reset --hard && | |
420 | test_ln_s_add foo foo4 && | |
9ebd7fe1 | 421 | test_must_fail git add --chmod=+x --dry-run foo4 2>stderr && |
48960894 | 422 | test_i18ngrep "cannot chmod +x .foo4." stderr |
c937d70b MT |
423 | ' |
424 | ||
425 | test_expect_success 'git add --chmod --dry-run reports error for unmatched pathspec' ' | |
426 | test_must_fail git add --chmod=+x --dry-run nonexistent 2>stderr && | |
427 | test_i18ngrep "pathspec .nonexistent. did not match any files" stderr | |
428 | ' | |
429 | ||
610d55af TG |
430 | test_expect_success 'no file status change if no pathspec is given' ' |
431 | >foo5 && | |
432 | >foo6 && | |
433 | git add foo5 foo6 && | |
434 | git add --chmod=+x && | |
435 | test_mode_in_index 100644 foo5 && | |
436 | test_mode_in_index 100644 foo6 | |
437 | ' | |
438 | ||
439 | test_expect_success 'no file status change if no pathspec is given in subdir' ' | |
b07ad464 | 440 | mkdir -p sub && |
610d55af TG |
441 | ( |
442 | cd sub && | |
443 | >sub-foo1 && | |
444 | >sub-foo2 && | |
445 | git add . && | |
446 | git add --chmod=+x && | |
447 | test_mode_in_index 100644 sub-foo1 && | |
448 | test_mode_in_index 100644 sub-foo2 | |
449 | ) | |
450 | ' | |
451 | ||
452 | test_expect_success 'all statuses changed in folder if . is given' ' | |
9ebd7fe1 MT |
453 | git init repo && |
454 | ( | |
455 | cd repo && | |
456 | mkdir -p sub/dir && | |
457 | touch x y z sub/a sub/dir/b && | |
458 | git add -A && | |
459 | git add --chmod=+x . && | |
460 | test $(git ls-files --stage | grep ^100644 | wc -l) -eq 0 && | |
461 | git add --chmod=-x . && | |
462 | test $(git ls-files --stage | grep ^100755 | wc -l) -eq 0 | |
463 | ) | |
610d55af TG |
464 | ' |
465 | ||
d8727b36 JS |
466 | test_expect_success CASE_INSENSITIVE_FS 'path is case-insensitive' ' |
467 | path="$(pwd)/BLUB" && | |
468 | touch "$path" && | |
469 | downcased="$(echo "$path" | tr A-Z a-z)" && | |
470 | git add "$downcased" | |
471 | ' | |
472 | ||
60ace879 | 473 | test_done |