]> git.ipfire.org Git - thirdparty/git.git/blob - t/t2501-cwd-empty.sh
The 19th batch
[thirdparty/git.git] / t / t2501-cwd-empty.sh
1 #!/bin/sh
2
3 test_description='Test handling of the current working directory becoming empty'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success setup '
9 test_commit init &&
10
11 git branch fd_conflict &&
12
13 mkdir -p foo/bar &&
14 test_commit foo/bar/baz &&
15
16 git revert HEAD &&
17 git tag reverted &&
18
19 git checkout fd_conflict &&
20 mkdir dirORfile &&
21 test_commit dirORfile/foo &&
22
23 git rm -r dirORfile &&
24 echo not-a-directory >dirORfile &&
25 git add dirORfile &&
26 git commit -m dirORfile &&
27
28 git switch -c df_conflict HEAD~1 &&
29 test_commit random_file &&
30
31 git switch -c undo_fd_conflict fd_conflict &&
32 git revert HEAD
33 '
34
35 test_incidental_dir_removal () {
36 test_when_finished "git reset --hard" &&
37
38 git checkout foo/bar/baz^{commit} &&
39 test_path_is_dir foo/bar &&
40
41 (
42 cd foo &&
43 "$@" &&
44
45 # Make sure foo still exists, and commands needing it work
46 test-tool getcwd &&
47 git status --porcelain
48 ) &&
49 test_path_is_missing foo/bar/baz &&
50 test_path_is_missing foo/bar &&
51
52 test_path_is_dir foo
53 }
54
55 test_required_dir_removal () {
56 git checkout df_conflict^{commit} &&
57 test_when_finished "git clean -fdx" &&
58
59 (
60 cd dirORfile &&
61
62 # Ensure command refuses to run
63 test_must_fail "$@" 2>../error &&
64 grep "Refusing to remove.*current working directory" ../error &&
65
66 # ...and that the index and working tree are left clean
67 git diff --exit-code HEAD &&
68
69 # Ensure that getcwd and git status do not error out (which
70 # they might if the current working directory had been removed)
71 test-tool getcwd &&
72 git status --porcelain
73 ) &&
74
75 test_path_is_dir dirORfile
76 }
77
78 test_expect_success 'checkout does not clean cwd incidentally' '
79 test_incidental_dir_removal git checkout init
80 '
81
82 test_expect_success 'checkout fails if cwd needs to be removed' '
83 test_required_dir_removal git checkout fd_conflict
84 '
85
86 test_expect_success 'reset --hard does not clean cwd incidentally' '
87 test_incidental_dir_removal git reset --hard init
88 '
89
90 test_expect_success 'reset --hard fails if cwd needs to be removed' '
91 test_required_dir_removal git reset --hard fd_conflict
92 '
93
94 test_expect_success 'merge does not clean cwd incidentally' '
95 test_incidental_dir_removal git merge reverted
96 '
97
98 # This file uses some simple merges where
99 # Base: 'dirORfile/' exists
100 # Side1: random other file changed
101 # Side2: 'dirORfile/' removed, 'dirORfile' added
102 # this should resolve cleanly, but merge-recursive throws merge conflicts
103 # because it's dumb. Add a special test for checking merge-recursive (and
104 # merge-ort), then after this just hard require ort for all remaining tests.
105 #
106 test_expect_success 'merge fails if cwd needs to be removed; recursive friendly' '
107 git checkout foo/bar/baz &&
108 test_when_finished "git clean -fdx" &&
109
110 mkdir dirORfile &&
111 (
112 cd dirORfile &&
113
114 test_must_fail git merge fd_conflict 2>../error
115 ) &&
116
117 test_path_is_dir dirORfile &&
118 grep "Refusing to remove the current working directory" error
119 '
120
121 GIT_TEST_MERGE_ALGORITHM=ort
122
123 test_expect_success 'merge fails if cwd needs to be removed' '
124 test_required_dir_removal git merge fd_conflict
125 '
126
127 test_expect_success 'cherry-pick does not clean cwd incidentally' '
128 test_incidental_dir_removal git cherry-pick reverted
129 '
130
131 test_expect_success 'cherry-pick fails if cwd needs to be removed' '
132 test_required_dir_removal git cherry-pick fd_conflict
133 '
134
135 test_expect_success 'rebase does not clean cwd incidentally' '
136 test_incidental_dir_removal git rebase reverted
137 '
138
139 test_expect_success 'rebase fails if cwd needs to be removed' '
140 test_required_dir_removal git rebase fd_conflict
141 '
142
143 test_expect_success 'revert does not clean cwd incidentally' '
144 test_incidental_dir_removal git revert HEAD
145 '
146
147 test_expect_success 'revert fails if cwd needs to be removed' '
148 test_required_dir_removal git revert undo_fd_conflict
149 '
150
151 test_expect_success 'rm does not clean cwd incidentally' '
152 test_incidental_dir_removal git rm bar/baz.t
153 '
154
155 test_expect_success 'apply does not remove cwd incidentally' '
156 git diff HEAD HEAD~1 >patch &&
157 test_incidental_dir_removal git apply ../patch
158 '
159
160 test_incidental_untracked_dir_removal () {
161 test_when_finished "git reset --hard" &&
162
163 git checkout foo/bar/baz^{commit} &&
164 mkdir -p untracked &&
165 mkdir empty
166 >untracked/random &&
167
168 (
169 cd untracked &&
170 "$@" &&
171
172 # Make sure untracked still exists, and commands needing it work
173 test-tool getcwd &&
174 git status --porcelain
175 ) &&
176 test_path_is_missing empty &&
177 test_path_is_missing untracked/random &&
178
179 test_path_is_dir untracked
180 }
181
182 test_expect_success 'clean does not remove cwd incidentally' '
183 test_incidental_untracked_dir_removal \
184 git -C .. clean -fd -e warnings . >warnings &&
185 grep "Refusing to remove current working directory" warnings
186 '
187
188 test_expect_success 'stash does not remove cwd incidentally' '
189 test_incidental_untracked_dir_removal \
190 git stash --include-untracked
191 '
192
193 test_expect_success '`rm -rf dir` only removes a subset of dir' '
194 test_when_finished "rm -rf a/" &&
195
196 mkdir -p a/b/c &&
197 >a/b/c/untracked &&
198 >a/b/c/tracked &&
199 git add a/b/c/tracked &&
200
201 (
202 cd a/b &&
203 git rm -rf ../b
204 ) &&
205
206 test_path_is_dir a/b &&
207 test_path_is_missing a/b/c/tracked &&
208 test_path_is_file a/b/c/untracked
209 '
210
211 test_expect_success '`rm -rf dir` even with only tracked files will remove something else' '
212 test_when_finished "rm -rf a/" &&
213
214 mkdir -p a/b/c &&
215 >a/b/c/tracked &&
216 git add a/b/c/tracked &&
217
218 (
219 cd a/b &&
220 git rm -rf ../b
221 ) &&
222
223 test_path_is_missing a/b/c/tracked &&
224 test_path_is_missing a/b/c &&
225 test_path_is_dir a/b
226 '
227
228 test_expect_success 'git version continues working from a deleted dir' '
229 mkdir tmp &&
230 (
231 cd tmp &&
232 rm -rf ../tmp &&
233 git version
234 )
235 '
236
237 test_submodule_removal () {
238 path_status=$1 &&
239 shift &&
240
241 test_status=
242 test "$path_status" = dir && test_status=test_must_fail
243
244 test_when_finished "git reset --hard HEAD~1" &&
245 test_when_finished "rm -rf .git/modules/my_submodule" &&
246
247 git checkout foo/bar/baz &&
248
249 git init my_submodule &&
250 touch my_submodule/file &&
251 git -C my_submodule add file &&
252 git -C my_submodule commit -m "initial commit" &&
253 git submodule add ./my_submodule &&
254 git commit -m "Add the submodule" &&
255
256 (
257 cd my_submodule &&
258 $test_status "$@"
259 ) &&
260
261 test_path_is_${path_status} my_submodule
262 }
263
264 test_expect_success 'rm -r with -C leaves submodule if cwd inside' '
265 test_submodule_removal dir git -C .. rm -r my_submodule/
266 '
267
268 test_expect_success 'rm -r leaves submodule if cwd inside' '
269 test_submodule_removal dir \
270 git --git-dir=../.git --work-tree=.. rm -r ../my_submodule/
271 '
272
273 test_expect_success 'rm -rf removes submodule even if cwd inside' '
274 test_submodule_removal missing \
275 git --git-dir=../.git --work-tree=.. rm -rf ../my_submodule/
276 '
277
278 test_done