t / t3600-rm.shon commit t6500(mingw): use the Windows PID of the shell (c871fbe)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Carl D. Worth
   4#
   5
   6test_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
  11test_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
  17if test_have_prereq !FUNNYNAMES; then
  18        say 'Your filesystem does not allow tabs in filenames.'
  19fi
  20
  21test_expect_success FUNNYNAMES 'add files with funny names' "
  22     touch -- 'tab      embedded' 'newline
  23embedded' &&
  24     git add -- 'tab    embedded' 'newline
  25embedded' &&
  26     git commit -m 'add files with tabs and newlines'
  27"
  28
  29test_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
  33test_expect_success \
  34    'Test that git rm foo succeeds' \
  35    'git rm --cached foo'
  36
  37test_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
  43test_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
  51test_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
  62test_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
  72test_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
  76test_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
  80test_expect_success \
  81    'Test that "git rm bar" succeeds' \
  82    'git rm bar'
  83
  84test_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
  88test_expect_success \
  89    'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' \
  90    'git rm -- -q'
  91
  92test_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
  95embedded'"
  96
  97test_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
 103test_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
 107test_expect_success 'Remove nonexistent file with --ignore-unmatch' '
 108        git rm --ignore-unmatch nonexistent
 109'
 110
 111test_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
 121test_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.
 132test_expect_success 'Re-add foo and baz' '
 133        git add foo baz &&
 134        git ls-files --error-unmatch foo baz
 135'
 136
 137test_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
 145test_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
 153test_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
 160test_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
 167test_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
 175test_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
 182test_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
 188test_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
 195test_expect_success 'Recursive without -r fails' '
 196        test_must_fail git rm frotz &&
 197        test -d frotz &&
 198        test -f frotz/nitfol
 199'
 200
 201test_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
 208test_expect_success 'Recursive with -r -f' '
 209        git rm -f -r frotz &&
 210        ! test -f frotz/nitfol &&
 211        ! test -d frotz
 212'
 213
 214test_expect_success 'Remove nonexistent file returns nonzero exit status' '
 215        test_must_fail git rm nonexistent
 216'
 217
 218test_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
 230test_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
 239test_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
 252test_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
 260cat >expect <<EOF
 261M  .gitmodules
 262D  submod
 263EOF
 264
 265cat >expect.modified <<EOF
 266 M submod
 267EOF
 268
 269cat >expect.modified_inside <<EOF
 270 m submod
 271EOF
 272
 273cat >expect.modified_untracked <<EOF
 274 ? submod
 275EOF
 276
 277cat >expect.cached <<EOF
 278D  submod
 279EOF
 280
 281cat >expect.both_deleted<<EOF
 282D  .gitmodules
 283D  submod
 284EOF
 285
 286test_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
 302test_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
 313test_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
 324test_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
 333test_expect_success 'rm fails when given a file with a trailing /' '
 334        test_must_fail git rm empty/
 335'
 336
 337test_expect_success 'rm succeeds when given a directory with a trailing /' '
 338        git rm -r frotz/
 339'
 340
 341test_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
 358test_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
 370test_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
 378test_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
 390test_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
 408test_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
 422test_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
 437test_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
 452test_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
 474cat >expect.conflict <<EOF
 475UU submod
 476EOF
 477
 478test_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
 489test_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
 508test_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
 527test_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
 544test_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
 568test_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
 578test_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
 596cat >expect.deepmodified <<EOF
 597 M submod/subsubmod
 598EOF
 599
 600test_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
 615test_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
 622test_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
 637test_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
 652test_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
 667test_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
 683test_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
 698test_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
 710test_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
 723test_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
 735test_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
 749test_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
 763test_expect_success 'setup for testing rm messages' '
 764        >bar.txt &&
 765        >foo.txt &&
 766        git add bar.txt foo.txt
 767'
 768
 769test_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
 783test_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
 796test_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
 808test_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
 818test_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
 831test_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
 840test_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
 859test_expect_success 'rm empty string should fail' '
 860        test_must_fail git rm -rf ""
 861'
 862
 863test_done