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