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