]>
Commit | Line | Data |
---|---|---|
d4a1cab5 CW |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2006 Carl D. Worth | |
4 | # | |
5 | ||
5be60078 | 6 | test_description='Test of the various options to git rm.' |
d4a1cab5 | 7 | |
cbc75a12 | 8 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
9 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
10 | ||
d4a1cab5 CW |
11 | . ./test-lib.sh |
12 | ||
3844cdc8 | 13 | # Setup some files to be removed, some with funny characters |
b5368c23 RA |
14 | test_expect_success 'Initialize test directory' ' |
15 | touch -- foo bar baz "space embedded" -q && | |
16 | git add -- foo bar baz "space embedded" -q && | |
17 | git commit -m "add normal files" | |
18 | ' | |
56e78bfb | 19 | |
b5368c23 RA |
20 | if test_have_prereq !FUNNYNAMES |
21 | then | |
56e78bfb JS |
22 | say 'Your filesystem does not allow tabs in filenames.' |
23 | fi | |
24 | ||
b5368c23 RA |
25 | test_expect_success FUNNYNAMES 'add files with funny names' ' |
26 | touch -- "tab embedded" "newline${LF}embedded" && | |
27 | git add -- "tab embedded" "newline${LF}embedded" && | |
28 | git commit -m "add files with tabs and newlines" | |
29 | ' | |
30 | ||
31 | test_expect_success 'Pre-check that foo exists and is in index before git rm foo' ' | |
59a06e94 | 32 | test_path_is_file foo && |
b5368c23 RA |
33 | git ls-files --error-unmatch foo |
34 | ' | |
35 | ||
36 | test_expect_success 'Test that git rm foo succeeds' ' | |
37 | git rm --cached foo | |
38 | ' | |
39 | ||
40 | test_expect_success 'Test that git rm --cached foo succeeds if the index matches the file' ' | |
41 | echo content >foo && | |
42 | git add foo && | |
43 | git rm --cached foo | |
44 | ' | |
45 | ||
46 | test_expect_success 'Test that git rm --cached foo succeeds if the index matches the file' ' | |
47 | echo content >foo && | |
48 | git add foo && | |
49 | git commit -m foo && | |
50 | echo "other content" >foo && | |
51 | git rm --cached foo | |
52 | ' | |
53 | ||
54 | test_expect_success 'Test that git rm --cached foo fails if the index matches neither the file nor HEAD' ' | |
55 | echo content >foo && | |
56 | git add foo && | |
57 | git commit -m foo --allow-empty && | |
58 | echo "other content" >foo && | |
59 | git add foo && | |
60 | echo "yet another content" >foo && | |
61 | test_must_fail git rm --cached foo | |
62 | ' | |
63 | ||
64 | test_expect_success 'Test that git rm --cached -f foo works in case where --cached only did not' ' | |
65 | echo content >foo && | |
66 | git add foo && | |
67 | git commit -m foo --allow-empty && | |
68 | echo "other content" >foo && | |
69 | git add foo && | |
70 | echo "yet another content" >foo && | |
71 | git rm --cached -f foo | |
72 | ' | |
73 | ||
74 | test_expect_success 'Post-check that foo exists but is not in index after git rm foo' ' | |
59a06e94 | 75 | test_path_is_file foo && |
b5368c23 RA |
76 | test_must_fail git ls-files --error-unmatch foo |
77 | ' | |
78 | ||
79 | test_expect_success 'Pre-check that bar exists and is in index before "git rm bar"' ' | |
59a06e94 | 80 | test_path_is_file bar && |
b5368c23 RA |
81 | git ls-files --error-unmatch bar |
82 | ' | |
83 | ||
84 | test_expect_success 'Test that "git rm bar" succeeds' ' | |
85 | git rm bar | |
86 | ' | |
87 | ||
88 | test_expect_success 'Post-check that bar does not exist and is not in index after "git rm -f bar"' ' | |
59a06e94 | 89 | test_path_is_missing bar && |
b5368c23 RA |
90 | test_must_fail git ls-files --error-unmatch bar |
91 | ' | |
92 | ||
93 | test_expect_success 'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' ' | |
94 | git rm -- -q | |
95 | ' | |
96 | ||
97 | test_expect_success FUNNYNAMES 'Test that "git rm -f" succeeds with embedded space, tab, or newline characters.' ' | |
98 | git rm -f "space embedded" "tab embedded" "newline${LF}embedded" | |
99 | ' | |
3844cdc8 | 100 | |
fbbfc8a9 | 101 | test_expect_success SANITY 'Test that "git rm -f" fails if its rm fails' ' |
23739aa2 | 102 | test_when_finished "chmod 775 ." && |
56e78bfb | 103 | chmod a-w . && |
23739aa2 | 104 | test_must_fail git rm -f baz |
56e78bfb | 105 | ' |
3844cdc8 | 106 | |
b5368c23 RA |
107 | test_expect_success 'When the rm in "git rm -f" fails, it should not remove the file from the index' ' |
108 | git ls-files --error-unmatch baz | |
109 | ' | |
3844cdc8 | 110 | |
bb1faf0d SG |
111 | test_expect_success 'Remove nonexistent file with --ignore-unmatch' ' |
112 | git rm --ignore-unmatch nonexistent | |
113 | ' | |
114 | ||
b48caa20 | 115 | test_expect_success '"rm" command printed' ' |
9e189f1a | 116 | echo frotz >test-file && |
b48caa20 SG |
117 | git add test-file && |
118 | git commit -m "add file for rm test" && | |
0d913dfa DL |
119 | git rm test-file >rm-output.raw && |
120 | grep "^rm " rm-output.raw >rm-output && | |
121 | test_line_count = 1 rm-output && | |
122 | rm -f test-file rm-output.raw rm-output && | |
b48caa20 SG |
123 | git commit -m "remove file from rm test" |
124 | ' | |
125 | ||
126 | test_expect_success '"rm" command suppressed with --quiet' ' | |
9e189f1a | 127 | echo frotz >test-file && |
b48caa20 SG |
128 | git add test-file && |
129 | git commit -m "add file for rm --quiet test" && | |
9e189f1a SB |
130 | git rm --quiet test-file >rm-output && |
131 | test_must_be_empty rm-output && | |
b48caa20 SG |
132 | rm -f test-file rm-output && |
133 | git commit -m "remove file from rm --quiet test" | |
134 | ' | |
135 | ||
467e1b53 JH |
136 | # Now, failure cases. |
137 | test_expect_success 'Re-add foo and baz' ' | |
138 | git add foo baz && | |
139 | git ls-files --error-unmatch foo baz | |
140 | ' | |
141 | ||
142 | test_expect_success 'Modify foo -- rm should refuse' ' | |
143 | echo >>foo && | |
d492b31c | 144 | test_must_fail git rm foo baz && |
59a06e94 RA |
145 | test_path_is_file foo && |
146 | test_path_is_file baz && | |
467e1b53 JH |
147 | git ls-files --error-unmatch foo baz |
148 | ' | |
149 | ||
150 | test_expect_success 'Modified foo -- rm -f should work' ' | |
151 | git rm -f foo baz && | |
59a06e94 RA |
152 | test_path_is_missing foo && |
153 | test_path_is_missing baz && | |
d492b31c SB |
154 | test_must_fail git ls-files --error-unmatch foo && |
155 | test_must_fail git ls-files --error-unmatch bar | |
467e1b53 JH |
156 | ' |
157 | ||
158 | test_expect_success 'Re-add foo and baz for HEAD tests' ' | |
159 | echo frotz >foo && | |
160 | git checkout HEAD -- baz && | |
161 | git add foo baz && | |
162 | git ls-files --error-unmatch foo baz | |
163 | ' | |
164 | ||
165 | test_expect_success 'foo is different in index from HEAD -- rm should refuse' ' | |
d492b31c | 166 | test_must_fail git rm foo baz && |
59a06e94 RA |
167 | test_path_is_file foo && |
168 | test_path_is_file baz && | |
467e1b53 JH |
169 | git ls-files --error-unmatch foo baz |
170 | ' | |
171 | ||
172 | test_expect_success 'but with -f it should work.' ' | |
173 | git rm -f foo baz && | |
59a06e94 RA |
174 | test_path_is_missing foo && |
175 | test_path_is_missing baz && | |
8fb26872 | 176 | test_must_fail git ls-files --error-unmatch foo && |
d492b31c | 177 | test_must_fail git ls-files --error-unmatch baz |
467e1b53 JH |
178 | ' |
179 | ||
388b2acd JH |
180 | test_expect_success 'refuse to remove cached empty file with modifications' ' |
181 | >empty && | |
f55527f8 JK |
182 | git add empty && |
183 | echo content >empty && | |
184 | test_must_fail git rm --cached empty | |
185 | ' | |
186 | ||
187 | test_expect_success 'remove intent-to-add file without --force' ' | |
188 | echo content >intent-to-add && | |
99094a7a | 189 | git add -N intent-to-add && |
f55527f8 JK |
190 | git rm --cached intent-to-add |
191 | ' | |
192 | ||
467e1b53 JH |
193 | test_expect_success 'Recursive test setup' ' |
194 | mkdir -p frotz && | |
195 | echo qfwfq >frotz/nitfol && | |
196 | git add frotz && | |
197 | git commit -m "subdir test" | |
198 | ' | |
199 | ||
200 | test_expect_success 'Recursive without -r fails' ' | |
d492b31c | 201 | test_must_fail git rm frotz && |
59a06e94 RA |
202 | test_path_is_dir frotz && |
203 | test_path_is_file frotz/nitfol | |
467e1b53 JH |
204 | ' |
205 | ||
206 | test_expect_success 'Recursive with -r but dirty' ' | |
99094a7a | 207 | echo qfwfq >>frotz/nitfol && |
d492b31c | 208 | test_must_fail git rm -r frotz && |
59a06e94 RA |
209 | test_path_is_dir frotz && |
210 | test_path_is_file frotz/nitfol | |
467e1b53 JH |
211 | ' |
212 | ||
213 | test_expect_success 'Recursive with -r -f' ' | |
214 | git rm -f -r frotz && | |
59a06e94 RA |
215 | test_path_is_missing frotz/nitfol && |
216 | test_path_is_missing frotz | |
467e1b53 JH |
217 | ' |
218 | ||
41ac414e | 219 | test_expect_success 'Remove nonexistent file returns nonzero exit status' ' |
d492b31c | 220 | test_must_fail git rm nonexistent |
b48caa20 SG |
221 | ' |
222 | ||
4d264672 OM |
223 | test_expect_success 'Call "rm" from outside the work tree' ' |
224 | mkdir repo && | |
b5368c23 RA |
225 | ( |
226 | cd repo && | |
227 | git init && | |
228 | echo something >somefile && | |
229 | git add somefile && | |
230 | git commit -m "add a file" && | |
231 | ( | |
232 | cd .. && | |
233 | git --git-dir=repo/.git --work-tree=repo rm somefile | |
234 | ) && | |
235 | test_must_fail git ls-files --error-unmatch somefile | |
236 | ) | |
cced48a8 JS |
237 | ' |
238 | ||
239 | test_expect_success 'refresh index before checking if it is up-to-date' ' | |
cced48a8 | 240 | git reset --hard && |
0e496492 | 241 | test-tool chmtime -86400 frotz/nitfol && |
cced48a8 | 242 | git rm frotz/nitfol && |
59a06e94 | 243 | test_path_is_missing frotz/nitfol |
4d264672 OM |
244 | ' |
245 | ||
db89a82b | 246 | choke_git_rm_setup() { |
0693f9dd | 247 | git reset -q --hard && |
056f34bb | 248 | test_when_finished "rm -f .git/index.lock && git reset -q --hard" && |
0693f9dd | 249 | i=0 && |
ca6ba942 | 250 | hash=$(test_oid deadbeef) && |
0693f9dd JH |
251 | while test $i -lt 12000 |
252 | do | |
ca6ba942 | 253 | echo "100644 $hash 0 some-file-$i" |
b5368c23 | 254 | i=$(( $i + 1 )) |
db89a82b ÆAB |
255 | done | git update-index --index-info |
256 | } | |
257 | ||
258 | test_expect_success 'choking "git rm" should not let it die with cruft (induce SIGPIPE)' ' | |
259 | choke_git_rm_setup && | |
50cd31c6 | 260 | # git command is intentionally placed upstream of pipe to induce SIGPIPE |
056f34bb SG |
261 | git rm -n "some-file-*" | : && |
262 | test_path_is_missing .git/index.lock | |
0693f9dd JH |
263 | ' |
264 | ||
db89a82b ÆAB |
265 | |
266 | test_expect_success !MINGW 'choking "git rm" should not let it die with cruft (induce and check SIGPIPE)' ' | |
267 | choke_git_rm_setup && | |
c576868e | 268 | OUT=$( ((trap "" PIPE && git rm -n "some-file-*"; echo $? 1>&3) | :) 3>&1 ) && |
db89a82b ÆAB |
269 | test_match_signal 13 "$OUT" && |
270 | test_path_is_missing .git/index.lock | |
271 | ' | |
272 | ||
b2b1f615 JH |
273 | test_expect_success 'Resolving by removal is not a warning-worthy event' ' |
274 | git reset -q --hard && | |
275 | test_when_finished "rm -f .git/index.lock msg && git reset -q --hard" && | |
276 | blob=$(echo blob | git hash-object -w --stdin) && | |
efe26b9e | 277 | printf "100644 $blob %d\tblob\n" 1 2 3 | git update-index --index-info && |
b2b1f615 JH |
278 | git rm blob >msg 2>&1 && |
279 | test_i18ngrep ! "needs merge" msg && | |
280 | test_must_fail git ls-files -s --error-unmatch blob | |
281 | ' | |
282 | ||
3fc0d131 JK |
283 | test_expect_success 'rm removes subdirectories recursively' ' |
284 | mkdir -p dir/subdir/subsubdir && | |
285 | echo content >dir/subdir/subsubdir/file && | |
286 | git add dir/subdir/subsubdir/file && | |
287 | git rm -f dir/subdir/subsubdir/file && | |
59a06e94 | 288 | test_path_is_missing dir |
3fc0d131 JK |
289 | ' |
290 | ||
293ab15e | 291 | cat >expect <<EOF |
95c16418 | 292 | M .gitmodules |
293ab15e JL |
293 | D submod |
294 | EOF | |
295 | ||
296 | cat >expect.modified <<EOF | |
297 | M submod | |
298 | EOF | |
299 | ||
dd6962dd SB |
300 | cat >expect.modified_inside <<EOF |
301 | m submod | |
302 | EOF | |
303 | ||
304 | cat >expect.modified_untracked <<EOF | |
305 | ? submod | |
306 | EOF | |
307 | ||
95c16418 JL |
308 | cat >expect.cached <<EOF |
309 | D submod | |
310 | EOF | |
311 | ||
312 | cat >expect.both_deleted<<EOF | |
313 | D .gitmodules | |
314 | D submod | |
315 | EOF | |
316 | ||
293ab15e JL |
317 | test_expect_success 'rm removes empty submodules from work tree' ' |
318 | mkdir submod && | |
3b737381 DL |
319 | hash=$(git rev-parse HEAD) && |
320 | git update-index --add --cacheinfo 160000 "$hash" submod && | |
293ab15e JL |
321 | git config -f .gitmodules submodule.sub.url ./. && |
322 | git config -f .gitmodules submodule.sub.path submod && | |
323 | git submodule init && | |
324 | git add .gitmodules && | |
325 | git commit -m "add submodule" && | |
326 | git rm submod && | |
59a06e94 | 327 | test_path_is_missing submod && |
9e189f1a | 328 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
329 | test_cmp expect actual && |
330 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
331 | test_must_fail git config -f .gitmodules submodule.sub.path | |
293ab15e JL |
332 | ' |
333 | ||
95c16418 | 334 | test_expect_success 'rm removes removed submodule from index and .gitmodules' ' |
293ab15e | 335 | git reset --hard && |
f8d510ed | 336 | git -c protocol.file.allow=always submodule update && |
293ab15e JL |
337 | rm -rf submod && |
338 | git rm submod && | |
9e189f1a | 339 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
340 | test_cmp expect actual && |
341 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
342 | test_must_fail git config -f .gitmodules submodule.sub.path | |
293ab15e JL |
343 | ' |
344 | ||
345 | test_expect_success 'rm removes work tree of unmodified submodules' ' | |
346 | git reset --hard && | |
347 | git submodule update && | |
348 | git rm submod && | |
59a06e94 | 349 | test_path_is_missing submod && |
9e189f1a | 350 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
351 | test_cmp expect actual && |
352 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
353 | test_must_fail git config -f .gitmodules submodule.sub.path | |
293ab15e JL |
354 | ' |
355 | ||
53e4c5dc JL |
356 | test_expect_success 'rm removes a submodule with a trailing /' ' |
357 | git reset --hard && | |
358 | git submodule update && | |
359 | git rm submod/ && | |
59a06e94 | 360 | test_path_is_missing submod && |
9e189f1a | 361 | git status -s -uno --ignore-submodules=none >actual && |
53e4c5dc JL |
362 | test_cmp expect actual |
363 | ' | |
364 | ||
365 | test_expect_success 'rm fails when given a file with a trailing /' ' | |
366 | test_must_fail git rm empty/ | |
367 | ' | |
368 | ||
369 | test_expect_success 'rm succeeds when given a directory with a trailing /' ' | |
370 | git rm -r frotz/ | |
371 | ' | |
372 | ||
293ab15e JL |
373 | test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' ' |
374 | git reset --hard && | |
375 | git submodule update && | |
9e189f1a | 376 | git -C submod checkout HEAD^ && |
293ab15e | 377 | test_must_fail git rm submod && |
59a06e94 RA |
378 | test_path_is_dir submod && |
379 | test_path_is_file submod/.git && | |
9e189f1a | 380 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
381 | test_cmp expect.modified actual && |
382 | git rm -f submod && | |
59a06e94 | 383 | test_path_is_missing submod && |
9e189f1a | 384 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
385 | test_cmp expect actual && |
386 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
387 | test_must_fail git config -f .gitmodules submodule.sub.path | |
388 | ' | |
389 | ||
390 | test_expect_success 'rm --cached leaves work tree of populated submodules and .gitmodules alone' ' | |
391 | git reset --hard && | |
392 | git submodule update && | |
393 | git rm --cached submod && | |
59a06e94 RA |
394 | test_path_is_dir submod && |
395 | test_path_is_file submod/.git && | |
95c16418 JL |
396 | git status -s -uno >actual && |
397 | test_cmp expect.cached actual && | |
398 | git config -f .gitmodules submodule.sub.url && | |
399 | git config -f .gitmodules submodule.sub.path | |
400 | ' | |
401 | ||
402 | test_expect_success 'rm --dry-run does not touch the submodule or .gitmodules' ' | |
403 | git reset --hard && | |
404 | git submodule update && | |
405 | git rm -n submod && | |
59a06e94 | 406 | test_path_is_file submod/.git && |
95c16418 JL |
407 | git diff-index --exit-code HEAD |
408 | ' | |
409 | ||
410 | test_expect_success 'rm does not complain when no .gitmodules file is found' ' | |
411 | git reset --hard && | |
412 | git submodule update && | |
413 | git rm .gitmodules && | |
414 | git rm submod >actual 2>actual.err && | |
ec10b018 | 415 | test_must_be_empty actual.err && |
59a06e94 RA |
416 | test_path_is_missing submod && |
417 | test_path_is_missing submod/.git && | |
95c16418 JL |
418 | git status -s -uno >actual && |
419 | test_cmp expect.both_deleted actual | |
420 | ' | |
421 | ||
422 | test_expect_success 'rm will error out on a modified .gitmodules file unless staged' ' | |
423 | git reset --hard && | |
424 | git submodule update && | |
425 | git config -f .gitmodules foo.bar true && | |
426 | test_must_fail git rm submod >actual 2>actual.err && | |
59a06e94 RA |
427 | test_file_not_empty actual.err && |
428 | test_path_is_dir submod && | |
429 | test_path_is_file submod/.git && | |
95c16418 JL |
430 | git diff-files --quiet -- submod && |
431 | git add .gitmodules && | |
432 | git rm submod >actual 2>actual.err && | |
ec10b018 | 433 | test_must_be_empty actual.err && |
59a06e94 RA |
434 | test_path_is_missing submod && |
435 | test_path_is_missing submod/.git && | |
95c16418 JL |
436 | git status -s -uno >actual && |
437 | test_cmp expect actual | |
438 | ' | |
7edee329 DT |
439 | test_expect_success 'rm will not error out on .gitmodules file with zero stat data' ' |
440 | git reset --hard && | |
441 | git submodule update && | |
442 | git read-tree HEAD && | |
443 | git rm submod && | |
444 | test_path_is_missing submod | |
445 | ' | |
95c16418 JL |
446 | |
447 | test_expect_success 'rm issues a warning when section is not found in .gitmodules' ' | |
448 | git reset --hard && | |
449 | git submodule update && | |
450 | git config -f .gitmodules --remove-section submodule.sub && | |
451 | git add .gitmodules && | |
452 | echo "warning: Could not find section in .gitmodules where path=submod" >expect.err && | |
453 | git rm submod >actual 2>actual.err && | |
1108cea7 | 454 | test_cmp expect.err actual.err && |
59a06e94 RA |
455 | test_path_is_missing submod && |
456 | test_path_is_missing submod/.git && | |
95c16418 | 457 | git status -s -uno >actual && |
293ab15e JL |
458 | test_cmp expect actual |
459 | ' | |
460 | ||
461 | test_expect_success 'rm of a populated submodule with modifications fails unless forced' ' | |
462 | git reset --hard && | |
463 | git submodule update && | |
9e189f1a | 464 | echo X >submod/empty && |
293ab15e | 465 | test_must_fail git rm submod && |
59a06e94 RA |
466 | test_path_is_dir submod && |
467 | test_path_is_file submod/.git && | |
9e189f1a | 468 | git status -s -uno --ignore-submodules=none >actual && |
dd6962dd | 469 | test_cmp expect.modified_inside actual && |
293ab15e | 470 | git rm -f submod && |
59a06e94 | 471 | test_path_is_missing submod && |
9e189f1a | 472 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
473 | test_cmp expect actual |
474 | ' | |
475 | ||
476 | test_expect_success 'rm of a populated submodule with untracked files fails unless forced' ' | |
477 | git reset --hard && | |
478 | git submodule update && | |
9e189f1a | 479 | echo X >submod/untracked && |
293ab15e | 480 | test_must_fail git rm submod && |
59a06e94 RA |
481 | test_path_is_dir submod && |
482 | test_path_is_file submod/.git && | |
9e189f1a | 483 | git status -s -uno --ignore-submodules=none >actual && |
dd6962dd | 484 | test_cmp expect.modified_untracked actual && |
293ab15e | 485 | git rm -f submod && |
59a06e94 | 486 | test_path_is_missing submod && |
9e189f1a | 487 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
488 | test_cmp expect actual |
489 | ' | |
490 | ||
491 | test_expect_success 'setup submodule conflict' ' | |
492 | git reset --hard && | |
493 | git submodule update && | |
494 | git checkout -b branch1 && | |
495 | echo 1 >nitfol && | |
496 | git add nitfol && | |
497 | git commit -m "added nitfol 1" && | |
cbc75a12 | 498 | git checkout -b branch2 main && |
293ab15e JL |
499 | echo 2 >nitfol && |
500 | git add nitfol && | |
501 | git commit -m "added nitfol 2" && | |
cbc75a12 | 502 | git checkout -b conflict1 main && |
9e189f1a SB |
503 | git -C submod fetch && |
504 | git -C submod checkout branch1 && | |
293ab15e JL |
505 | git add submod && |
506 | git commit -m "submod 1" && | |
cbc75a12 | 507 | git checkout -b conflict2 main && |
9e189f1a | 508 | git -C submod checkout branch2 && |
293ab15e JL |
509 | git add submod && |
510 | git commit -m "submod 2" | |
511 | ' | |
512 | ||
513 | cat >expect.conflict <<EOF | |
514 | UU submod | |
515 | EOF | |
516 | ||
517 | test_expect_success 'rm removes work tree of unmodified conflicted submodule' ' | |
518 | git checkout conflict1 && | |
519 | git reset --hard && | |
520 | git submodule update && | |
521 | test_must_fail git merge conflict2 && | |
522 | git rm submod && | |
59a06e94 | 523 | test_path_is_missing submod && |
9e189f1a | 524 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
525 | test_cmp expect actual |
526 | ' | |
527 | ||
528 | test_expect_success 'rm of a conflicted populated submodule with different HEAD fails unless forced' ' | |
529 | git checkout conflict1 && | |
530 | git reset --hard && | |
531 | git submodule update && | |
9e189f1a | 532 | git -C submod checkout HEAD^ && |
293ab15e JL |
533 | test_must_fail git merge conflict2 && |
534 | test_must_fail git rm submod && | |
59a06e94 RA |
535 | test_path_is_dir submod && |
536 | test_path_is_file submod/.git && | |
9e189f1a | 537 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
538 | test_cmp expect.conflict actual && |
539 | git rm -f submod && | |
59a06e94 | 540 | test_path_is_missing submod && |
9e189f1a | 541 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
542 | test_cmp expect actual && |
543 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
544 | test_must_fail git config -f .gitmodules submodule.sub.path | |
293ab15e JL |
545 | ' |
546 | ||
547 | test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' ' | |
548 | git checkout conflict1 && | |
549 | git reset --hard && | |
550 | git submodule update && | |
9e189f1a | 551 | echo X >submod/empty && |
293ab15e JL |
552 | test_must_fail git merge conflict2 && |
553 | test_must_fail git rm submod && | |
59a06e94 RA |
554 | test_path_is_dir submod && |
555 | test_path_is_file submod/.git && | |
9e189f1a | 556 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
557 | test_cmp expect.conflict actual && |
558 | git rm -f submod && | |
59a06e94 | 559 | test_path_is_missing submod && |
9e189f1a | 560 | git status -s -uno --ignore-submodules=none >actual && |
95c16418 JL |
561 | test_cmp expect actual && |
562 | test_must_fail git config -f .gitmodules submodule.sub.url && | |
563 | test_must_fail git config -f .gitmodules submodule.sub.path | |
293ab15e JL |
564 | ' |
565 | ||
566 | test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' ' | |
567 | git checkout conflict1 && | |
568 | git reset --hard && | |
569 | git submodule update && | |
9e189f1a | 570 | echo X >submod/untracked && |
293ab15e JL |
571 | test_must_fail git merge conflict2 && |
572 | test_must_fail git rm submod && | |
59a06e94 RA |
573 | test_path_is_dir submod && |
574 | test_path_is_file submod/.git && | |
9e189f1a | 575 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
576 | test_cmp expect.conflict actual && |
577 | git rm -f submod && | |
59a06e94 | 578 | test_path_is_missing submod && |
9e189f1a | 579 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
580 | test_cmp expect actual |
581 | ' | |
582 | ||
583 | test_expect_success 'rm of a conflicted populated submodule with a .git directory fails even when forced' ' | |
584 | git checkout conflict1 && | |
585 | git reset --hard && | |
586 | git submodule update && | |
b5368c23 RA |
587 | ( |
588 | cd submod && | |
293ab15e | 589 | rm .git && |
2d3ac9ad | 590 | cp -R ../.git/modules/sub .git && |
293ab15e JL |
591 | GIT_WORK_TREE=. git config --unset core.worktree |
592 | ) && | |
593 | test_must_fail git merge conflict2 && | |
594 | test_must_fail git rm submod && | |
59a06e94 RA |
595 | test_path_is_dir submod && |
596 | test_path_is_dir submod/.git && | |
9e189f1a | 597 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
598 | test_cmp expect.conflict actual && |
599 | test_must_fail git rm -f submod && | |
59a06e94 RA |
600 | test_path_is_dir submod && |
601 | test_path_is_dir submod/.git && | |
9e189f1a | 602 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
603 | test_cmp expect.conflict actual && |
604 | git merge --abort && | |
605 | rm -rf submod | |
606 | ' | |
607 | ||
608 | test_expect_success 'rm of a conflicted unpopulated submodule succeeds' ' | |
609 | git checkout conflict1 && | |
610 | git reset --hard && | |
611 | test_must_fail git merge conflict2 && | |
612 | git rm submod && | |
59a06e94 | 613 | test_path_is_missing submod && |
9e189f1a | 614 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
615 | test_cmp expect actual |
616 | ' | |
617 | ||
55856a35 | 618 | test_expect_success 'rm of a populated submodule with a .git directory migrates git dir' ' |
cbc75a12 | 619 | git checkout -f main && |
293ab15e JL |
620 | git reset --hard && |
621 | git submodule update && | |
b5368c23 RA |
622 | ( |
623 | cd submod && | |
293ab15e | 624 | rm .git && |
2d3ac9ad | 625 | cp -R ../.git/modules/sub .git && |
55856a35 SB |
626 | GIT_WORK_TREE=. git config --unset core.worktree && |
627 | rm -r ../.git/modules/sub | |
293ab15e | 628 | ) && |
55856a35 | 629 | git rm submod 2>output.err && |
59a06e94 RA |
630 | test_path_is_missing submod && |
631 | test_path_is_missing submod/.git && | |
9e189f1a | 632 | git status -s -uno --ignore-submodules=none >actual && |
59a06e94 | 633 | test_file_not_empty actual && |
55856a35 | 634 | test_i18ngrep Migrating output.err |
293ab15e JL |
635 | ' |
636 | ||
637 | cat >expect.deepmodified <<EOF | |
638 | M submod/subsubmod | |
639 | EOF | |
640 | ||
641 | test_expect_success 'setup subsubmodule' ' | |
f8d510ed | 642 | test_config_global protocol.file.allow always && |
293ab15e JL |
643 | git reset --hard && |
644 | git submodule update && | |
b5368c23 RA |
645 | ( |
646 | cd submod && | |
3b737381 DL |
647 | hash=$(git rev-parse HEAD) && |
648 | git update-index --add --cacheinfo 160000 "$hash" subsubmod && | |
293ab15e JL |
649 | git config -f .gitmodules submodule.sub.url ../. && |
650 | git config -f .gitmodules submodule.sub.path subsubmod && | |
651 | git submodule init && | |
652 | git add .gitmodules && | |
653 | git commit -m "add subsubmodule" && | |
654 | git submodule update subsubmod | |
655 | ) && | |
656 | git commit -a -m "added deep submodule" | |
657 | ' | |
658 | ||
659 | test_expect_success 'rm recursively removes work tree of unmodified submodules' ' | |
660 | git rm submod && | |
59a06e94 | 661 | test_path_is_missing submod && |
9e189f1a | 662 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
663 | test_cmp expect actual |
664 | ' | |
665 | ||
666 | test_expect_success 'rm of a populated nested submodule with different nested HEAD fails unless forced' ' | |
667 | git reset --hard && | |
668 | git submodule update --recursive && | |
9e189f1a | 669 | git -C submod/subsubmod checkout HEAD^ && |
293ab15e | 670 | test_must_fail git rm submod && |
59a06e94 RA |
671 | test_path_is_dir submod && |
672 | test_path_is_file submod/.git && | |
9e189f1a | 673 | git status -s -uno --ignore-submodules=none >actual && |
dd6962dd | 674 | test_cmp expect.modified_inside actual && |
293ab15e | 675 | git rm -f submod && |
59a06e94 | 676 | test_path_is_missing submod && |
9e189f1a | 677 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
678 | test_cmp expect actual |
679 | ' | |
680 | ||
681 | test_expect_success 'rm of a populated nested submodule with nested modifications fails unless forced' ' | |
682 | git reset --hard && | |
683 | git submodule update --recursive && | |
9e189f1a | 684 | echo X >submod/subsubmod/empty && |
293ab15e | 685 | test_must_fail git rm submod && |
59a06e94 RA |
686 | test_path_is_dir submod && |
687 | test_path_is_file submod/.git && | |
9e189f1a | 688 | git status -s -uno --ignore-submodules=none >actual && |
dd6962dd | 689 | test_cmp expect.modified_inside actual && |
293ab15e | 690 | git rm -f submod && |
59a06e94 | 691 | test_path_is_missing submod && |
9e189f1a | 692 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
693 | test_cmp expect actual |
694 | ' | |
695 | ||
696 | test_expect_success 'rm of a populated nested submodule with nested untracked files fails unless forced' ' | |
697 | git reset --hard && | |
698 | git submodule update --recursive && | |
9e189f1a | 699 | echo X >submod/subsubmod/untracked && |
293ab15e | 700 | test_must_fail git rm submod && |
59a06e94 RA |
701 | test_path_is_dir submod && |
702 | test_path_is_file submod/.git && | |
9e189f1a | 703 | git status -s -uno --ignore-submodules=none >actual && |
40069d6e | 704 | test_cmp expect.modified_untracked actual && |
293ab15e | 705 | git rm -f submod && |
59a06e94 | 706 | test_path_is_missing submod && |
9e189f1a | 707 | git status -s -uno --ignore-submodules=none >actual && |
293ab15e JL |
708 | test_cmp expect actual |
709 | ' | |
710 | ||
70471ed9 | 711 | test_expect_success "rm absorbs submodule's nested .git directory" ' |
293ab15e JL |
712 | git reset --hard && |
713 | git submodule update --recursive && | |
b5368c23 RA |
714 | ( |
715 | cd submod/subsubmod && | |
293ab15e | 716 | rm .git && |
55856a35 | 717 | mv ../../.git/modules/sub/modules/sub .git && |
293ab15e JL |
718 | GIT_WORK_TREE=. git config --unset core.worktree |
719 | ) && | |
55856a35 | 720 | git rm submod 2>output.err && |
59a06e94 RA |
721 | test_path_is_missing submod && |
722 | test_path_is_missing submod/subsubmod/.git && | |
9e189f1a | 723 | git status -s -uno --ignore-submodules=none >actual && |
59a06e94 | 724 | test_file_not_empty actual && |
55856a35 | 725 | test_i18ngrep Migrating output.err |
293ab15e JL |
726 | ' |
727 | ||
bbad9f93 | 728 | test_expect_success 'checking out a commit after submodule removal needs manual updates' ' |
55856a35 | 729 | git commit -m "submodule removal" submod .gitmodules && |
bbad9f93 JL |
730 | git checkout HEAD^ && |
731 | git submodule update && | |
8954bd76 | 732 | git checkout -q HEAD^ && |
cbc75a12 | 733 | git checkout -q main 2>actual && |
0a288d1e | 734 | test_i18ngrep "^warning: unable to rmdir '\''submod'\'':" actual && |
bbad9f93 JL |
735 | git status -s submod >actual && |
736 | echo "?? submod/" >expected && | |
737 | test_cmp expected actual && | |
738 | rm -rf submod && | |
9e189f1a | 739 | git status -s -uno --ignore-submodules=none >actual && |
ec10b018 | 740 | test_must_be_empty actual |
bbad9f93 JL |
741 | ' |
742 | ||
9a6728d4 JK |
743 | test_expect_success 'rm of d/f when d has become a non-directory' ' |
744 | rm -rf d && | |
745 | mkdir d && | |
746 | >d/f && | |
747 | git add d && | |
748 | rm -rf d && | |
749 | >d && | |
750 | git rm d/f && | |
751 | test_must_fail git rev-parse --verify :d/f && | |
752 | test_path_is_file d | |
753 | ' | |
754 | ||
755 | test_expect_success SYMLINKS 'rm of d/f when d has become a dangling symlink' ' | |
756 | rm -rf d && | |
757 | mkdir d && | |
758 | >d/f && | |
759 | git add d && | |
760 | rm -rf d && | |
761 | ln -s nonexistent d && | |
762 | git rm d/f && | |
763 | test_must_fail git rev-parse --verify :d/f && | |
764 | test -h d && | |
765 | test_path_is_missing d | |
766 | ' | |
767 | ||
96ec8ee9 JK |
768 | test_expect_success 'rm of file when it has become a directory' ' |
769 | rm -rf d && | |
770 | >d && | |
771 | git add d && | |
772 | rm -f d && | |
773 | mkdir d && | |
774 | >d/f && | |
775 | test_must_fail git rm d && | |
776 | git rev-parse --verify :d && | |
777 | test_path_is_file d/f | |
778 | ' | |
779 | ||
03415ca8 JK |
780 | test_expect_success SYMLINKS 'rm across a symlinked leading path (no index)' ' |
781 | rm -rf d e && | |
782 | mkdir e && | |
783 | echo content >e/f && | |
784 | ln -s e d && | |
785 | git add -A e d && | |
786 | git commit -m "symlink d to e, e/f exists" && | |
787 | test_must_fail git rm d/f && | |
788 | git rev-parse --verify :d && | |
789 | git rev-parse --verify :e/f && | |
790 | test -h d && | |
791 | test_path_is_file e/f | |
792 | ' | |
793 | ||
794 | test_expect_failure SYMLINKS 'rm across a symlinked leading path (w/ index)' ' | |
795 | rm -rf d e && | |
796 | mkdir d && | |
797 | echo content >d/f && | |
798 | git add -A e d && | |
799 | git commit -m "d/f exists" && | |
800 | mv d e && | |
801 | ln -s e d && | |
802 | test_must_fail git rm d/f && | |
803 | git rev-parse --verify :d/f && | |
804 | test -h d && | |
805 | test_path_is_file e/f | |
806 | ' | |
807 | ||
914dc028 MLM |
808 | test_expect_success 'setup for testing rm messages' ' |
809 | >bar.txt && | |
810 | >foo.txt && | |
811 | git add bar.txt foo.txt | |
812 | ' | |
813 | ||
814 | test_expect_success 'rm files with different staged content' ' | |
815 | cat >expect <<-\EOF && | |
816 | error: the following files have staged content different from both the | |
817 | file and the HEAD: | |
818 | bar.txt | |
819 | foo.txt | |
820 | (use -f to force removal) | |
821 | EOF | |
822 | echo content1 >foo.txt && | |
823 | echo content1 >bar.txt && | |
824 | test_must_fail git rm foo.txt bar.txt 2>actual && | |
1108cea7 | 825 | test_cmp expect actual |
914dc028 MLM |
826 | ' |
827 | ||
7e309446 MLM |
828 | test_expect_success 'rm files with different staged content without hints' ' |
829 | cat >expect <<-\EOF && | |
830 | error: the following files have staged content different from both the | |
831 | file and the HEAD: | |
832 | bar.txt | |
833 | foo.txt | |
834 | EOF | |
835 | echo content2 >foo.txt && | |
836 | echo content2 >bar.txt && | |
837 | test_must_fail git -c advice.rmhints=false rm foo.txt bar.txt 2>actual && | |
1108cea7 | 838 | test_cmp expect actual |
7e309446 | 839 | ' |
914dc028 MLM |
840 | |
841 | test_expect_success 'rm file with local modification' ' | |
842 | cat >expect <<-\EOF && | |
843 | error: the following file has local modifications: | |
844 | foo.txt | |
845 | (use --cached to keep the file, or -f to force removal) | |
846 | EOF | |
847 | git commit -m "testing rm 3" && | |
848 | echo content3 >foo.txt && | |
849 | test_must_fail git rm foo.txt 2>actual && | |
1108cea7 | 850 | test_cmp expect actual |
914dc028 MLM |
851 | ' |
852 | ||
7e309446 MLM |
853 | test_expect_success 'rm file with local modification without hints' ' |
854 | cat >expect <<-\EOF && | |
855 | error: the following file has local modifications: | |
856 | bar.txt | |
857 | EOF | |
858 | echo content4 >bar.txt && | |
859 | test_must_fail git -c advice.rmhints=false rm bar.txt 2>actual && | |
1108cea7 | 860 | test_cmp expect actual |
7e309446 | 861 | ' |
914dc028 MLM |
862 | |
863 | test_expect_success 'rm file with changes in the index' ' | |
864 | cat >expect <<-\EOF && | |
865 | error: the following file has changes staged in the index: | |
866 | foo.txt | |
867 | (use --cached to keep the file, or -f to force removal) | |
868 | EOF | |
869 | git reset --hard && | |
870 | echo content5 >foo.txt && | |
871 | git add foo.txt && | |
872 | test_must_fail git rm foo.txt 2>actual && | |
1108cea7 | 873 | test_cmp expect actual |
914dc028 MLM |
874 | ' |
875 | ||
7e309446 MLM |
876 | test_expect_success 'rm file with changes in the index without hints' ' |
877 | cat >expect <<-\EOF && | |
878 | error: the following file has changes staged in the index: | |
879 | foo.txt | |
880 | EOF | |
881 | test_must_fail git -c advice.rmhints=false rm foo.txt 2>actual && | |
1108cea7 | 882 | test_cmp expect actual |
7e309446 | 883 | ' |
914dc028 MLM |
884 | |
885 | test_expect_success 'rm files with two different errors' ' | |
886 | cat >expect <<-\EOF && | |
887 | error: the following file has staged content different from both the | |
888 | file and the HEAD: | |
889 | foo1.txt | |
890 | (use -f to force removal) | |
891 | error: the following file has changes staged in the index: | |
892 | bar1.txt | |
893 | (use --cached to keep the file, or -f to force removal) | |
894 | EOF | |
895 | echo content >foo1.txt && | |
896 | git add foo1.txt && | |
897 | echo content6 >foo1.txt && | |
898 | echo content6 >bar1.txt && | |
899 | git add bar1.txt && | |
900 | test_must_fail git rm bar1.txt foo1.txt 2>actual && | |
1108cea7 | 901 | test_cmp expect actual |
914dc028 MLM |
902 | ' |
903 | ||
9e4e8a64 EX |
904 | test_expect_success 'rm empty string should fail' ' |
905 | test_must_fail git rm -rf "" | |
d426430e EX |
906 | ' |
907 | ||
d4a1cab5 | 908 | test_done |