You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
6.5 KiB
277 lines
6.5 KiB
#!/bin/sh |
|
|
|
test_description='Test handling of the current working directory becoming empty' |
|
|
|
. ./test-lib.sh |
|
|
|
test_expect_success setup ' |
|
test_commit init && |
|
|
|
git branch fd_conflict && |
|
|
|
mkdir -p foo/bar && |
|
test_commit foo/bar/baz && |
|
|
|
git revert HEAD && |
|
git tag reverted && |
|
|
|
git checkout fd_conflict && |
|
mkdir dirORfile && |
|
test_commit dirORfile/foo && |
|
|
|
git rm -r dirORfile && |
|
echo not-a-directory >dirORfile && |
|
git add dirORfile && |
|
git commit -m dirORfile && |
|
|
|
git switch -c df_conflict HEAD~1 && |
|
test_commit random_file && |
|
|
|
git switch -c undo_fd_conflict fd_conflict && |
|
git revert HEAD |
|
' |
|
|
|
test_incidental_dir_removal () { |
|
test_when_finished "git reset --hard" && |
|
|
|
git checkout foo/bar/baz^{commit} && |
|
test_path_is_dir foo/bar && |
|
|
|
( |
|
cd foo && |
|
"$@" && |
|
|
|
# Make sure foo still exists, and commands needing it work |
|
test-tool getcwd && |
|
git status --porcelain |
|
) && |
|
test_path_is_missing foo/bar/baz && |
|
test_path_is_missing foo/bar && |
|
|
|
test_path_is_dir foo |
|
} |
|
|
|
test_required_dir_removal () { |
|
git checkout df_conflict^{commit} && |
|
test_when_finished "git clean -fdx" && |
|
|
|
( |
|
cd dirORfile && |
|
|
|
# Ensure command refuses to run |
|
test_must_fail "$@" 2>../error && |
|
grep "Refusing to remove.*current working directory" ../error && |
|
|
|
# ...and that the index and working tree are left clean |
|
git diff --exit-code HEAD && |
|
|
|
# Ensure that getcwd and git status do not error out (which |
|
# they might if the current working directory had been removed) |
|
test-tool getcwd && |
|
git status --porcelain |
|
) && |
|
|
|
test_path_is_dir dirORfile |
|
} |
|
|
|
test_expect_success 'checkout does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git checkout init |
|
' |
|
|
|
test_expect_success 'checkout fails if cwd needs to be removed' ' |
|
test_required_dir_removal git checkout fd_conflict |
|
' |
|
|
|
test_expect_success 'reset --hard does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git reset --hard init |
|
' |
|
|
|
test_expect_success 'reset --hard fails if cwd needs to be removed' ' |
|
test_required_dir_removal git reset --hard fd_conflict |
|
' |
|
|
|
test_expect_success 'merge does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git merge reverted |
|
' |
|
|
|
# This file uses some simple merges where |
|
# Base: 'dirORfile/' exists |
|
# Side1: random other file changed |
|
# Side2: 'dirORfile/' removed, 'dirORfile' added |
|
# this should resolve cleanly, but merge-recursive throws merge conflicts |
|
# because it's dumb. Add a special test for checking merge-recursive (and |
|
# merge-ort), then after this just hard require ort for all remaining tests. |
|
# |
|
test_expect_success 'merge fails if cwd needs to be removed; recursive friendly' ' |
|
git checkout foo/bar/baz && |
|
test_when_finished "git clean -fdx" && |
|
|
|
mkdir dirORfile && |
|
( |
|
cd dirORfile && |
|
|
|
test_must_fail git merge fd_conflict 2>../error |
|
) && |
|
|
|
test_path_is_dir dirORfile && |
|
grep "Refusing to remove the current working directory" error |
|
' |
|
|
|
GIT_TEST_MERGE_ALGORITHM=ort |
|
|
|
test_expect_success 'merge fails if cwd needs to be removed' ' |
|
test_required_dir_removal git merge fd_conflict |
|
' |
|
|
|
test_expect_success 'cherry-pick does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git cherry-pick reverted |
|
' |
|
|
|
test_expect_success 'cherry-pick fails if cwd needs to be removed' ' |
|
test_required_dir_removal git cherry-pick fd_conflict |
|
' |
|
|
|
test_expect_success 'rebase does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git rebase reverted |
|
' |
|
|
|
test_expect_success 'rebase fails if cwd needs to be removed' ' |
|
test_required_dir_removal git rebase fd_conflict |
|
' |
|
|
|
test_expect_success 'revert does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git revert HEAD |
|
' |
|
|
|
test_expect_success 'revert fails if cwd needs to be removed' ' |
|
test_required_dir_removal git revert undo_fd_conflict |
|
' |
|
|
|
test_expect_success 'rm does not clean cwd incidentally' ' |
|
test_incidental_dir_removal git rm bar/baz.t |
|
' |
|
|
|
test_expect_success 'apply does not remove cwd incidentally' ' |
|
git diff HEAD HEAD~1 >patch && |
|
test_incidental_dir_removal git apply ../patch |
|
' |
|
|
|
test_incidental_untracked_dir_removal () { |
|
test_when_finished "git reset --hard" && |
|
|
|
git checkout foo/bar/baz^{commit} && |
|
mkdir -p untracked && |
|
mkdir empty |
|
>untracked/random && |
|
|
|
( |
|
cd untracked && |
|
"$@" && |
|
|
|
# Make sure untracked still exists, and commands needing it work |
|
test-tool getcwd && |
|
git status --porcelain |
|
) && |
|
test_path_is_missing empty && |
|
test_path_is_missing untracked/random && |
|
|
|
test_path_is_dir untracked |
|
} |
|
|
|
test_expect_success 'clean does not remove cwd incidentally' ' |
|
test_incidental_untracked_dir_removal \ |
|
git -C .. clean -fd -e warnings . >warnings && |
|
grep "Refusing to remove current working directory" warnings |
|
' |
|
|
|
test_expect_success 'stash does not remove cwd incidentally' ' |
|
test_incidental_untracked_dir_removal \ |
|
git stash --include-untracked |
|
' |
|
|
|
test_expect_success '`rm -rf dir` only removes a subset of dir' ' |
|
test_when_finished "rm -rf a/" && |
|
|
|
mkdir -p a/b/c && |
|
>a/b/c/untracked && |
|
>a/b/c/tracked && |
|
git add a/b/c/tracked && |
|
|
|
( |
|
cd a/b && |
|
git rm -rf ../b |
|
) && |
|
|
|
test_path_is_dir a/b && |
|
test_path_is_missing a/b/c/tracked && |
|
test_path_is_file a/b/c/untracked |
|
' |
|
|
|
test_expect_success '`rm -rf dir` even with only tracked files will remove something else' ' |
|
test_when_finished "rm -rf a/" && |
|
|
|
mkdir -p a/b/c && |
|
>a/b/c/tracked && |
|
git add a/b/c/tracked && |
|
|
|
( |
|
cd a/b && |
|
git rm -rf ../b |
|
) && |
|
|
|
test_path_is_missing a/b/c/tracked && |
|
test_path_is_missing a/b/c && |
|
test_path_is_dir a/b |
|
' |
|
|
|
test_expect_success 'git version continues working from a deleted dir' ' |
|
mkdir tmp && |
|
( |
|
cd tmp && |
|
rm -rf ../tmp && |
|
git version |
|
) |
|
' |
|
|
|
test_submodule_removal () { |
|
path_status=$1 && |
|
shift && |
|
|
|
test_status= |
|
test "$path_status" = dir && test_status=test_must_fail |
|
|
|
test_when_finished "git reset --hard HEAD~1" && |
|
test_when_finished "rm -rf .git/modules/my_submodule" && |
|
|
|
git checkout foo/bar/baz && |
|
|
|
git init my_submodule && |
|
touch my_submodule/file && |
|
git -C my_submodule add file && |
|
git -C my_submodule commit -m "initial commit" && |
|
git submodule add ./my_submodule && |
|
git commit -m "Add the submodule" && |
|
|
|
( |
|
cd my_submodule && |
|
$test_status "$@" |
|
) && |
|
|
|
test_path_is_${path_status} my_submodule |
|
} |
|
|
|
test_expect_success 'rm -r with -C leaves submodule if cwd inside' ' |
|
test_submodule_removal dir git -C .. rm -r my_submodule/ |
|
' |
|
|
|
test_expect_success 'rm -r leaves submodule if cwd inside' ' |
|
test_submodule_removal dir \ |
|
git --git-dir=../.git --work-tree=.. rm -r ../my_submodule/ |
|
' |
|
|
|
test_expect_success 'rm -rf removes submodule even if cwd inside' ' |
|
test_submodule_removal missing \ |
|
git --git-dir=../.git --work-tree=.. rm -rf ../my_submodule/ |
|
' |
|
|
|
test_done
|
|
|