Merge branch 'master' of git://github.com/git-l10n/git-po
[gitweb.git] / t / t3600-rm.sh
index 79c06adf1f035cf727771974b2f9713da9d2fb8c..97254e8d337ff066f633ece5d1a7c8a59108e703 100755 (executable)
@@ -12,30 +12,21 @@ test_expect_success \
     'Initialize test directory' \
     "touch -- foo bar baz 'space embedded' -q &&
      git add -- foo bar baz 'space embedded' -q &&
-     git-commit -m 'add normal files' &&
-     test_tabs=y &&
-     if touch -- 'tab  embedded' 'newline
-embedded'
-     then
+     git commit -m 'add normal files'"
+
+if touch -- 'tab       embedded' 'newline
+embedded' 2>/dev/null
+then
+       test_set_prereq FUNNYNAMES
+else
+       say 'Your filesystem does not allow tabs in filenames.'
+fi
+
+test_expect_success FUNNYNAMES 'add files with funny names' "
      git add -- 'tab   embedded' 'newline
 embedded' &&
-     git-commit -m 'add files with tabs and newlines'
-     else
-         say 'Your filesystem does not allow tabs in filenames.'
-         test_tabs=n
-     fi"
-
-# Later we will try removing an unremovable path to make sure
-# git rm barfs, but if the test is run as root that cannot be
-# arranged.
-test_expect_success \
-    'Determine rm behavior' \
-    ': >test-file
-     chmod a-w .
-     rm -f test-file
-     test -f test-file && test_failed_remove=y
-     chmod 775 .
-     rm -f test-file'
+     git commit -m 'add files with tabs and newlines'
+"
 
 test_expect_success \
     'Pre-check that foo exists and is in index before git rm foo' \
@@ -100,20 +91,16 @@ test_expect_success \
     'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' \
     'git rm -- -q'
 
-test "$test_tabs" = y && test_expect_success \
+test_expect_success FUNNYNAMES \
     "Test that \"git rm -f\" succeeds with embedded space, tab, or newline characters." \
     "git rm -f 'space embedded' 'tab   embedded' 'newline
 embedded'"
 
-if test "$test_failed_remove" = y; then
-chmod a-w .
-test_expect_success \
-    'Test that "git rm -f" fails if its rm fails' \
-    'test_must_fail git rm -f baz'
-chmod 775 .
-else
-    test_expect_success 'skipping removal failure (perhaps running as root?)' :
-fi
+test_expect_success SANITY 'Test that "git rm -f" fails if its rm fails' '
+       chmod a-w . &&
+       test_must_fail git rm -f baz &&
+       chmod 775 .
+'
 
 test_expect_success \
     'When the rm in "git rm -f" fails, it should not remove the file from the index' \
@@ -187,6 +174,19 @@ test_expect_success 'but with -f it should work.' '
        test_must_fail git ls-files --error-unmatch baz
 '
 
+test_expect_success 'refuse to remove cached empty file with modifications' '
+       >empty &&
+       git add empty &&
+       echo content >empty &&
+       test_must_fail git rm --cached empty
+'
+
+test_expect_success 'remove intent-to-add file without --force' '
+       echo content >intent-to-add &&
+       git add -N intent-to-add
+       git rm --cached intent-to-add
+'
+
 test_expect_success 'Recursive test setup' '
        mkdir -p frotz &&
        echo qfwfq >frotz/nitfol &&
@@ -219,14 +219,390 @@ test_expect_success 'Remove nonexistent file returns nonzero exit status' '
 
 test_expect_success 'Call "rm" from outside the work tree' '
        mkdir repo &&
-       cd repo &&
-       git init &&
-       echo something > somefile &&
-       git add somefile &&
-       git commit -m "add a file" &&
-       (cd .. &&
-        git --git-dir=repo/.git --work-tree=repo rm somefile) &&
-       test_must_fail git ls-files --error-unmatch somefile
+       (cd repo &&
+        git init &&
+        echo something > somefile &&
+        git add somefile &&
+        git commit -m "add a file" &&
+        (cd .. &&
+         git --git-dir=repo/.git --work-tree=repo rm somefile) &&
+       test_must_fail git ls-files --error-unmatch somefile)
+'
+
+test_expect_success 'refresh index before checking if it is up-to-date' '
+
+       git reset --hard &&
+       test-chmtime -86400 frotz/nitfol &&
+       git rm frotz/nitfol &&
+       test ! -f frotz/nitfol
+
+'
+
+test_expect_success 'choking "git rm" should not let it die with cruft' '
+       git reset -q --hard &&
+       i=0 &&
+       while test $i -lt 12000
+       do
+           echo "100644 $_z40 0        some-file-$i"
+           i=$(( $i + 1 ))
+       done | git update-index --index-info &&
+       git rm -n "some-file-*" | :;
+       test -f .git/index.lock
+       status=$?
+       rm -f .git/index.lock
+       git reset -q --hard
+       test "$status" != 0
+'
+
+test_expect_success 'rm removes subdirectories recursively' '
+       mkdir -p dir/subdir/subsubdir &&
+       echo content >dir/subdir/subsubdir/file &&
+       git add dir/subdir/subsubdir/file &&
+       git rm -f dir/subdir/subsubdir/file &&
+       ! test -d dir
+'
+
+cat >expect <<EOF
+D  submod
+EOF
+
+cat >expect.modified <<EOF
+ M submod
+EOF
+
+test_expect_success 'rm removes empty submodules from work tree' '
+       mkdir submod &&
+       git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod &&
+       git config -f .gitmodules submodule.sub.url ./. &&
+       git config -f .gitmodules submodule.sub.path submod &&
+       git submodule init &&
+       git add .gitmodules &&
+       git commit -m "add submodule" &&
+       git rm submod &&
+       test ! -e submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm removes removed submodule from index' '
+       git reset --hard &&
+       git submodule update &&
+       rm -rf submod &&
+       git rm submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm removes work tree of unmodified submodules' '
+       git reset --hard &&
+       git submodule update &&
+       git rm submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' '
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               git checkout HEAD^
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with modifications fails unless forced' '
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               echo X >empty
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with untracked files fails unless forced' '
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               echo X >untracked
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'setup submodule conflict' '
+       git reset --hard &&
+       git submodule update &&
+       git checkout -b branch1 &&
+       echo 1 >nitfol &&
+       git add nitfol &&
+       git commit -m "added nitfol 1" &&
+       git checkout -b branch2 master &&
+       echo 2 >nitfol &&
+       git add nitfol &&
+       git commit -m "added nitfol 2" &&
+       git checkout -b conflict1 master &&
+       (cd submod &&
+               git fetch &&
+               git checkout branch1
+       ) &&
+       git add submod &&
+       git commit -m "submod 1" &&
+       git checkout -b conflict2 master &&
+       (cd submod &&
+               git checkout branch2
+       ) &&
+       git add submod &&
+       git commit -m "submod 2"
+'
+
+cat >expect.conflict <<EOF
+UU submod
+EOF
+
+test_expect_success 'rm removes work tree of unmodified conflicted submodule' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       git submodule update &&
+       test_must_fail git merge conflict2 &&
+       git rm submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with different HEAD fails unless forced' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               git checkout HEAD^
+       ) &&
+       test_must_fail git merge conflict2 &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.conflict actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               echo X >empty
+       ) &&
+       test_must_fail git merge conflict2 &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.conflict actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               echo X >untracked
+       ) &&
+       test_must_fail git merge conflict2 &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.conflict actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with a .git directory fails even when forced' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               rm .git &&
+               cp -a ../.git/modules/sub .git &&
+               GIT_WORK_TREE=. git config --unset core.worktree
+       ) &&
+       test_must_fail git merge conflict2 &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -d submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.conflict actual &&
+       test_must_fail git rm -f submod &&
+       test -d submod &&
+       test -d submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.conflict actual &&
+       git merge --abort &&
+       rm -rf submod
+'
+
+test_expect_success 'rm of a conflicted unpopulated submodule succeeds' '
+       git checkout conflict1 &&
+       git reset --hard &&
+       test_must_fail git merge conflict2 &&
+       git rm submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with a .git directory fails even when forced' '
+       git checkout -f master &&
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               rm .git &&
+               cp -a ../.git/modules/sub .git &&
+               GIT_WORK_TREE=. git config --unset core.worktree
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -d submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       ! test -s actual &&
+       test_must_fail git rm -f submod &&
+       test -d submod &&
+       test -d submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       ! test -s actual &&
+       rm -rf submod
+'
+
+cat >expect.deepmodified <<EOF
+ M submod/subsubmod
+EOF
+
+test_expect_success 'setup subsubmodule' '
+       git reset --hard &&
+       git submodule update &&
+       (cd submod &&
+               git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod &&
+               git config -f .gitmodules submodule.sub.url ../. &&
+               git config -f .gitmodules submodule.sub.path subsubmod &&
+               git submodule init &&
+               git add .gitmodules &&
+               git commit -m "add subsubmodule" &&
+               git submodule update subsubmod
+       ) &&
+       git commit -a -m "added deep submodule"
+'
+
+test_expect_success 'rm recursively removes work tree of unmodified submodules' '
+       git rm submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with different nested HEAD fails unless forced' '
+       git reset --hard &&
+       git submodule update --recursive &&
+       (cd submod/subsubmod &&
+               git checkout HEAD^
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested modifications fails unless forced' '
+       git reset --hard &&
+       git submodule update --recursive &&
+       (cd submod/subsubmod &&
+               echo X >empty
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested untracked files fails unless forced' '
+       git reset --hard &&
+       git submodule update --recursive &&
+       (cd submod/subsubmod &&
+               echo X >untracked
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -f submod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect.modified actual &&
+       git rm -f submod &&
+       test ! -d submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with a nested .git directory fails even when forced' '
+       git reset --hard &&
+       git submodule update --recursive &&
+       (cd submod/subsubmod &&
+               rm .git &&
+               cp -a ../../.git/modules/sub/modules/sub .git &&
+               GIT_WORK_TREE=. git config --unset core.worktree
+       ) &&
+       test_must_fail git rm submod &&
+       test -d submod &&
+       test -d submod/subsubmod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       ! test -s actual &&
+       test_must_fail git rm -f submod &&
+       test -d submod &&
+       test -d submod/subsubmod/.git &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       ! test -s actual &&
+       rm -rf submod
 '
 
 test_done