3 test_description
='Test handling of the current working directory becoming empty'
7 test_expect_success setup
'
10 git branch fd_conflict &&
13 test_commit foo/bar/baz &&
18 git checkout fd_conflict &&
20 test_commit dirORfile/foo &&
22 git rm -r dirORfile &&
23 echo not-a-directory >dirORfile &&
25 git commit -m dirORfile &&
27 git switch -c df_conflict HEAD~1 &&
28 test_commit random_file &&
30 git switch -c undo_fd_conflict fd_conflict &&
34 test_incidental_dir_removal
() {
35 test_when_finished
"git reset --hard" &&
37 git checkout foo
/bar
/baz^
{commit
} &&
38 test_path_is_dir foo
/bar
&&
44 # Make sure foo still exists, and commands needing it work
46 git status
--porcelain
48 test_path_is_missing foo
/bar
/baz
&&
49 test_path_is_missing foo
/bar
&&
54 test_required_dir_removal
() {
55 git checkout df_conflict^
{commit
} &&
56 test_when_finished
"git clean -fdx" &&
61 # Ensure command refuses to run
62 test_must_fail
"$@" 2>..
/error
&&
63 grep "Refusing to remove.*current working directory" ..
/error
&&
65 # ...and that the index and working tree are left clean
66 git
diff --exit-code HEAD
&&
68 # Ensure that getcwd and git status do not error out (which
69 # they might if the current working directory had been removed)
71 git status
--porcelain
74 test_path_is_dir dirORfile
77 test_expect_success
'checkout does not clean cwd incidentally' '
78 test_incidental_dir_removal git checkout init
81 test_expect_success
'checkout fails if cwd needs to be removed' '
82 test_required_dir_removal git checkout fd_conflict
85 test_expect_success
'reset --hard does not clean cwd incidentally' '
86 test_incidental_dir_removal git reset --hard init
89 test_expect_success
'reset --hard fails if cwd needs to be removed' '
90 test_required_dir_removal git reset --hard fd_conflict
93 test_expect_success
'merge does not clean cwd incidentally' '
94 test_incidental_dir_removal git merge reverted
97 # This file uses some simple merges where
98 # Base: 'dirORfile/' exists
99 # Side1: random other file changed
100 # Side2: 'dirORfile/' removed, 'dirORfile' added
101 # this should resolve cleanly, but merge-recursive throws merge conflicts
102 # because it's dumb. Add a special test for checking merge-recursive (and
103 # merge-ort), then after this just hard require ort for all remaining tests.
105 test_expect_success
'merge fails if cwd needs to be removed; recursive friendly' '
106 git checkout foo/bar/baz &&
107 test_when_finished "git clean -fdx" &&
113 test_must_fail git merge fd_conflict 2>../error
116 test_path_is_dir dirORfile &&
117 grep "Refusing to remove the current working directory" error
120 GIT_TEST_MERGE_ALGORITHM
=ort
122 test_expect_success
'merge fails if cwd needs to be removed' '
123 test_required_dir_removal git merge fd_conflict
126 test_expect_success
'cherry-pick does not clean cwd incidentally' '
127 test_incidental_dir_removal git cherry-pick reverted
130 test_expect_success
'cherry-pick fails if cwd needs to be removed' '
131 test_required_dir_removal git cherry-pick fd_conflict
134 test_expect_success
'rebase does not clean cwd incidentally' '
135 test_incidental_dir_removal git rebase reverted
138 test_expect_success
'rebase fails if cwd needs to be removed' '
139 test_required_dir_removal git rebase fd_conflict
142 test_expect_success
'revert does not clean cwd incidentally' '
143 test_incidental_dir_removal git revert HEAD
146 test_expect_success
'revert fails if cwd needs to be removed' '
147 test_required_dir_removal git revert undo_fd_conflict
150 test_expect_success
'rm does not clean cwd incidentally' '
151 test_incidental_dir_removal git rm bar/baz.t
154 test_expect_success
'apply does not remove cwd incidentally' '
155 git diff HEAD HEAD~1 >patch &&
156 test_incidental_dir_removal git apply ../patch
159 test_incidental_untracked_dir_removal
() {
160 test_when_finished
"git reset --hard" &&
162 git checkout foo
/bar
/baz^
{commit
} &&
163 mkdir
-p untracked
&&
171 # Make sure untracked still exists, and commands needing it work
173 git status
--porcelain
175 test_path_is_missing empty
&&
176 test_path_is_missing untracked
/random
&&
178 test_path_is_dir untracked
181 test_expect_success
'clean does not remove cwd incidentally' '
182 test_incidental_untracked_dir_removal \
183 git -C .. clean -fd -e warnings . >warnings &&
184 grep "Refusing to remove current working directory" warnings
187 test_expect_success
'stash does not remove cwd incidentally' '
188 test_incidental_untracked_dir_removal \
189 git stash --include-untracked
192 test_expect_success
'`rm -rf dir` only removes a subset of dir' '
193 test_when_finished "rm -rf a/" &&
198 git add a/b/c/tracked &&
205 test_path_is_dir a/b &&
206 test_path_is_missing a/b/c/tracked &&
207 test_path_is_file a/b/c/untracked
210 test_expect_success
'`rm -rf dir` even with only tracked files will remove something else' '
211 test_when_finished "rm -rf a/" &&
215 git add a/b/c/tracked &&
222 test_path_is_missing a/b/c/tracked &&
223 test_path_is_missing a/b/c &&
227 test_expect_success
'git version continues working from a deleted dir' '
236 test_submodule_removal
() {
241 test "$path_status" = dir
&& test_status
=test_must_fail
243 test_when_finished
"git reset --hard HEAD~1" &&
244 test_when_finished
"rm -rf .git/modules/my_submodule" &&
246 git checkout foo
/bar
/baz
&&
248 git init my_submodule
&&
249 touch my_submodule
/file &&
250 git
-C my_submodule add
file &&
251 git
-C my_submodule commit
-m "initial commit" &&
252 git submodule add .
/my_submodule
&&
253 git commit
-m "Add the submodule" &&
260 test_path_is_
${path_status} my_submodule
263 test_expect_success
'rm -r with -C leaves submodule if cwd inside' '
264 test_submodule_removal dir git -C .. rm -r my_submodule/
267 test_expect_success
'rm -r leaves submodule if cwd inside' '
268 test_submodule_removal dir \
269 git --git-dir=../.git --work-tree=.. rm -r ../my_submodule/
272 test_expect_success
'rm -rf removes submodule even if cwd inside' '
273 test_submodule_removal missing \
274 git --git-dir=../.git --work-tree=.. rm -rf ../my_submodule/