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