Merge branch 'sg/reflog-past-root' into maint
[git] / t / t3700-add.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Carl D. Worth
4 #
5
6 test_description='Test of git add, including the -- option.'
7
8 . ./test-lib.sh
9
10 test_expect_success \
11     'Test of git add' \
12     'touch foo && git add foo'
13
14 test_expect_success \
15     'Post-check that foo is in the index' \
16     'git ls-files foo | grep foo'
17
18 test_expect_success \
19     'Test that "git add -- -q" works' \
20     'touch -- -q && git add -- -q'
21
22 test_expect_success \
23         'git add: Test that executable bit is not used if core.filemode=0' \
24         'git config core.filemode 0 &&
25          echo foo >xfoo1 &&
26          chmod 755 xfoo1 &&
27          git add xfoo1 &&
28          case "$(git ls-files --stage xfoo1)" in
29          100644" "*xfoo1) echo pass;;
30          *) echo fail; git ls-files --stage xfoo1; (exit 1);;
31          esac'
32
33 test_expect_success 'git add: filemode=0 should not get confused by symlink' '
34         rm -f xfoo1 &&
35         test_ln_s_add foo xfoo1 &&
36         case "$(git ls-files --stage xfoo1)" in
37         120000" "*xfoo1) echo pass;;
38         *) echo fail; git ls-files --stage xfoo1; (exit 1);;
39         esac
40 '
41
42 test_expect_success \
43         'git update-index --add: Test that executable bit is not used...' \
44         'git config core.filemode 0 &&
45          echo foo >xfoo2 &&
46          chmod 755 xfoo2 &&
47          git update-index --add xfoo2 &&
48          case "$(git ls-files --stage xfoo2)" in
49          100644" "*xfoo2) echo pass;;
50          *) echo fail; git ls-files --stage xfoo2; (exit 1);;
51          esac'
52
53 test_expect_success 'git add: filemode=0 should not get confused by symlink' '
54         rm -f xfoo2 &&
55         test_ln_s_add foo xfoo2 &&
56         case "$(git ls-files --stage xfoo2)" in
57         120000" "*xfoo2) echo pass;;
58         *) echo fail; git ls-files --stage xfoo2; (exit 1);;
59         esac
60 '
61
62 test_expect_success \
63         'git update-index --add: Test that executable bit is not used...' \
64         'git config core.filemode 0 &&
65          test_ln_s_add xfoo2 xfoo3 &&   # runs git update-index --add
66          case "$(git ls-files --stage xfoo3)" in
67          120000" "*xfoo3) echo pass;;
68          *) echo fail; git ls-files --stage xfoo3; (exit 1);;
69          esac'
70
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' '
80         git add . &&
81         ! (git ls-files | grep "\\.ig")
82 '
83
84 test_expect_success 'error out when attempting to add ignored ones without -f' '
85         test_must_fail git add a.?? &&
86         ! (git ls-files | grep "\\.ig")
87 '
88
89 test_expect_success 'error out when attempting to add ignored ones without -f' '
90         test_must_fail git add d.?? &&
91         ! (git ls-files | grep "\\.ig")
92 '
93
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
101 test_expect_success 'add ignored ones with -f' '
102         git add -f a.?? &&
103         git ls-files --error-unmatch a.ig
104 '
105
106 test_expect_success 'add ignored ones with -f' '
107         git add -f d.??/* &&
108         git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
109 '
110
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
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' '
137         rm -f .git/index &&
138         git add 1/2/a 1/3/b 1/2/c
139 '
140
141 test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' '
142         for s in 1 2 3
143         do
144                 echo $s > stage$s
145                 echo "100755 $(git hash-object -w stage$s) $s   file"
146                 echo "120000 $(printf $s | git hash-object -w -t blob --stdin) $s       symlink"
147         done | git update-index --index-info &&
148         git config core.filemode 0 &&
149         git config core.symlinks 0 &&
150         echo new > file &&
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$"
155 '
156
157 test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' '
158         git rm --cached -f file symlink &&
159         (
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"
163                 echo "120000 $(printf 2 | git hash-object -w -t blob --stdin) 2 symlink"
164         ) | git update-index --index-info &&
165         git config core.filemode 0 &&
166         git config core.symlinks 0 &&
167         echo new > file &&
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$"
172 '
173
174 test_expect_success 'git add --refresh' '
175         >foo && git add foo && git commit -a -m "commit all" &&
176         test -z "$(git diff-index HEAD -- foo)" &&
177         git read-tree HEAD &&
178         case "$(git diff-index HEAD -- foo)" in
179         :100644" "*"M   foo") echo pass;;
180         *) echo fail; (exit 1);;
181         esac &&
182         git add --refresh -- foo &&
183         test -z "$(git diff-index HEAD -- foo)"
184 '
185
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 &&
191         test-chmtime -60 bar baz &&
192         >expect &&
193         git add --refresh bar >actual &&
194         test_cmp expect actual &&
195
196         git diff-files --name-only >actual &&
197         ! grep bar actual&&
198         grep baz actual
199 '
200
201 test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' '
202         git reset --hard &&
203         date >foo1 &&
204         date >foo2 &&
205         chmod 0 foo2 &&
206         test_must_fail git add --verbose . &&
207         ! ( git ls-files foo1 | grep foo1 )
208 '
209
210 rm -f foo2
211
212 test_expect_success POSIXPERM,SANITY 'git add --ignore-errors' '
213         git reset --hard &&
214         date >foo1 &&
215         date >foo2 &&
216         chmod 0 foo2 &&
217         test_must_fail git add --verbose --ignore-errors . &&
218         git ls-files foo1 | grep foo1
219 '
220
221 rm -f foo2
222
223 test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors)' '
224         git config add.ignore-errors 1 &&
225         git reset --hard &&
226         date >foo1 &&
227         date >foo2 &&
228         chmod 0 foo2 &&
229         test_must_fail git add --verbose . &&
230         git ls-files foo1 | grep foo1
231 '
232 rm -f foo2
233
234 test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors = false)' '
235         git config add.ignore-errors 0 &&
236         git reset --hard &&
237         date >foo1 &&
238         date >foo2 &&
239         chmod 0 foo2 &&
240         test_must_fail git add --verbose . &&
241         ! ( git ls-files foo1 | grep foo1 )
242 '
243 rm -f foo2
244
245 test_expect_success POSIXPERM,SANITY '--no-ignore-errors overrides config' '
246        git config add.ignore-errors 1 &&
247        git reset --hard &&
248        date >foo1 &&
249        date >foo2 &&
250        chmod 0 foo2 &&
251        test_must_fail git add --verbose --no-ignore-errors . &&
252        ! ( git ls-files foo1 | grep foo1 ) &&
253        git config add.ignore-errors 0
254 '
255 rm -f foo2
256
257 test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
258         git reset --hard &&
259         touch fo\[ou\]bar foobar &&
260         git add '\''fo\[ou\]bar'\'' &&
261         git ls-files fo\[ou\]bar | fgrep fo\[ou\]bar &&
262         ! ( git ls-files foobar | grep foobar )
263 '
264
265 test_expect_success 'git add to resolve conflicts on otherwise ignored path' '
266         git reset --hard &&
267         H=$(git rev-parse :1/2/a) &&
268         (
269                 echo "100644 $H 1       track-this"
270                 echo "100644 $H 3       track-this"
271         ) | git update-index --index-info &&
272         echo track-this >>.gitignore &&
273         echo resolved >track-this &&
274         git add track-this
275 '
276
277 test_expect_success '"add non-existent" should fail' '
278         test_must_fail git add non-existent &&
279         ! (git ls-files | grep "non-existent")
280 '
281
282 test_expect_success 'git add -A on empty repo does not error out' '
283         rm -fr empty &&
284         git init empty &&
285         (
286                 cd empty &&
287                 git add -A . &&
288                 git add -A
289         )
290 '
291
292 test_expect_success '"git add ." in empty repo' '
293         rm -fr empty &&
294         git init empty &&
295         (
296                 cd empty &&
297                 git add .
298         )
299 '
300
301 test_expect_success 'git add --dry-run of existing changed file' "
302         echo new >>track-this &&
303         git add --dry-run track-this >actual 2>&1 &&
304         echo \"add 'track-this'\" | test_cmp - actual
305 "
306
307 test_expect_success 'git add --dry-run of non-existing file' "
308         echo ignored-file >>.gitignore &&
309         test_must_fail git add --dry-run track-this ignored-file >actual 2>&1
310 "
311
312 test_expect_success 'git add --dry-run of an existing file output' "
313         echo \"fatal: pathspec 'ignored-file' did not match any files\" >expect &&
314         test_i18ncmp expect actual
315 "
316
317 cat >expect.err <<\EOF
318 The following paths are ignored by one of your .gitignore files:
319 ignored-file
320 Use -f if you really want to add them.
321 EOF
322 cat >expect.out <<\EOF
323 add 'track-this'
324 EOF
325
326 test_expect_success 'git add --dry-run --ignore-missing of non-existing file' '
327         test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err
328 '
329
330 test_expect_success 'git add --dry-run --ignore-missing of non-existing file output' '
331         test_i18ncmp expect.out actual.out &&
332         test_i18ncmp expect.err actual.err
333 '
334
335 test_expect_success 'git add --chmod=+x stages a non-executable file with +x' '
336         echo foo >foo1 &&
337         git add --chmod=+x foo1 &&
338         case "$(git ls-files --stage foo1)" in
339         100755" "*foo1) echo pass;;
340         *) echo fail; git ls-files --stage foo1; (exit 1);;
341         esac
342 '
343
344 test_expect_success 'git add --chmod=-x stages an executable file with -x' '
345         echo foo >xfoo1 &&
346         chmod 755 xfoo1 &&
347         git add --chmod=-x xfoo1 &&
348         case "$(git ls-files --stage xfoo1)" in
349         100644" "*xfoo1) echo pass;;
350         *) echo fail; git ls-files --stage xfoo1; (exit 1);;
351         esac
352 '
353
354 test_expect_success POSIXPERM,SYMLINKS 'git add --chmod=+x with symlinks' '
355         git config core.filemode 1 &&
356         git config core.symlinks 1 &&
357         echo foo >foo2 &&
358         git add --chmod=+x foo2 &&
359         case "$(git ls-files --stage foo2)" in
360         100755" "*foo2) echo pass;;
361         *) echo fail; git ls-files --stage foo2; (exit 1);;
362         esac
363 '
364
365 test_done