]>
Commit | Line | Data |
---|---|---|
d887cc18 JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='compare & swap push force/delete safety' | |
4 | ||
3ac8f630 | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
d887cc18 JH |
8 | . ./test-lib.sh |
9 | ||
10 | setup_srcdst_basic () { | |
11 | rm -fr src dst && | |
12 | git clone --no-local . src && | |
13 | git clone --no-local src dst && | |
14 | ( | |
15 | cd src && git checkout HEAD^0 | |
16 | ) | |
17 | } | |
18 | ||
3b5bf965 SK |
19 | # For tests with "--force-if-includes". |
20 | setup_src_dup_dst () { | |
21 | rm -fr src dup dst && | |
22 | git init --bare dst && | |
23 | git clone --no-local dst src && | |
24 | git clone --no-local dst dup | |
25 | ( | |
26 | cd src && | |
27 | test_commit A && | |
28 | test_commit B && | |
29 | test_commit C && | |
30 | git push origin | |
31 | ) && | |
32 | ( | |
33 | cd dup && | |
34 | git fetch && | |
3ac8f630 JS |
35 | git merge origin/main && |
36 | git switch -c branch main~2 && | |
3b5bf965 SK |
37 | test_commit D && |
38 | test_commit E && | |
39 | git push origin --all | |
40 | ) && | |
41 | ( | |
42 | cd src && | |
3ac8f630 | 43 | git switch main && |
3b5bf965 SK |
44 | git fetch --all && |
45 | git branch branch --track origin/branch && | |
3ac8f630 | 46 | git rebase origin/main |
3b5bf965 SK |
47 | ) && |
48 | ( | |
49 | cd dup && | |
3ac8f630 | 50 | git switch main && |
3b5bf965 SK |
51 | test_commit F && |
52 | test_commit G && | |
53 | git switch branch && | |
54 | test_commit H && | |
55 | git push origin --all | |
56 | ) | |
57 | } | |
58 | ||
d887cc18 | 59 | test_expect_success setup ' |
53350a35 | 60 | # create template repository |
d887cc18 JH |
61 | test_commit A && |
62 | test_commit B && | |
63 | test_commit C | |
64 | ' | |
65 | ||
66 | test_expect_success 'push to update (protected)' ' | |
67 | setup_srcdst_basic && | |
68 | ( | |
69 | cd dst && | |
70 | test_commit D && | |
3ac8f630 | 71 | test_must_fail git push --force-with-lease=main:main origin main 2>err && |
b2e93f88 | 72 | grep "stale info" err |
d887cc18 | 73 | ) && |
3ac8f630 JS |
74 | git ls-remote . refs/heads/main >expect && |
75 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
76 | test_cmp expect actual |
77 | ' | |
78 | ||
79 | test_expect_success 'push to update (protected, forced)' ' | |
80 | setup_srcdst_basic && | |
81 | ( | |
82 | cd dst && | |
83 | test_commit D && | |
3ac8f630 | 84 | git push --force --force-with-lease=main:main origin main 2>err && |
b2e93f88 | 85 | grep "forced update" err |
d887cc18 | 86 | ) && |
3ac8f630 JS |
87 | git ls-remote dst refs/heads/main >expect && |
88 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
89 | test_cmp expect actual |
90 | ' | |
91 | ||
92 | test_expect_success 'push to update (protected, tracking)' ' | |
93 | setup_srcdst_basic && | |
94 | ( | |
95 | cd src && | |
3ac8f630 | 96 | git checkout main && |
d887cc18 JH |
97 | test_commit D && |
98 | git checkout HEAD^0 | |
99 | ) && | |
3ac8f630 | 100 | git ls-remote src refs/heads/main >expect && |
d887cc18 JH |
101 | ( |
102 | cd dst && | |
103 | test_commit E && | |
3ac8f630 JS |
104 | git ls-remote . refs/remotes/origin/main >expect && |
105 | test_must_fail git push --force-with-lease=main origin main && | |
106 | git ls-remote . refs/remotes/origin/main >actual && | |
d887cc18 JH |
107 | test_cmp expect actual |
108 | ) && | |
3ac8f630 | 109 | git ls-remote src refs/heads/main >actual && |
d887cc18 JH |
110 | test_cmp expect actual |
111 | ' | |
112 | ||
113 | test_expect_success 'push to update (protected, tracking, forced)' ' | |
114 | setup_srcdst_basic && | |
115 | ( | |
116 | cd src && | |
3ac8f630 | 117 | git checkout main && |
d887cc18 JH |
118 | test_commit D && |
119 | git checkout HEAD^0 | |
120 | ) && | |
121 | ( | |
122 | cd dst && | |
123 | test_commit E && | |
3ac8f630 JS |
124 | git ls-remote . refs/remotes/origin/main >expect && |
125 | git push --force --force-with-lease=main origin main | |
d887cc18 | 126 | ) && |
3ac8f630 JS |
127 | git ls-remote dst refs/heads/main >expect && |
128 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
129 | test_cmp expect actual |
130 | ' | |
131 | ||
132 | test_expect_success 'push to update (allowed)' ' | |
133 | setup_srcdst_basic && | |
134 | ( | |
135 | cd dst && | |
136 | test_commit D && | |
3ac8f630 | 137 | git push --force-with-lease=main:main^ origin main |
d887cc18 | 138 | ) && |
3ac8f630 JS |
139 | git ls-remote dst refs/heads/main >expect && |
140 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
141 | test_cmp expect actual |
142 | ' | |
143 | ||
144 | test_expect_success 'push to update (allowed, tracking)' ' | |
145 | setup_srcdst_basic && | |
146 | ( | |
147 | cd dst && | |
148 | test_commit D && | |
3ac8f630 | 149 | git push --force-with-lease=main origin main 2>err && |
b2e93f88 | 150 | ! grep "forced update" err |
d887cc18 | 151 | ) && |
3ac8f630 JS |
152 | git ls-remote dst refs/heads/main >expect && |
153 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
154 | test_cmp expect actual |
155 | ' | |
156 | ||
157 | test_expect_success 'push to update (allowed even though no-ff)' ' | |
158 | setup_srcdst_basic && | |
159 | ( | |
160 | cd dst && | |
161 | git reset --hard HEAD^ && | |
162 | test_commit D && | |
3ac8f630 | 163 | git push --force-with-lease=main origin main 2>err && |
b2e93f88 | 164 | grep "forced update" err |
d887cc18 | 165 | ) && |
3ac8f630 JS |
166 | git ls-remote dst refs/heads/main >expect && |
167 | git ls-remote src refs/heads/main >actual && | |
d887cc18 JH |
168 | test_cmp expect actual |
169 | ' | |
170 | ||
171 | test_expect_success 'push to delete (protected)' ' | |
172 | setup_srcdst_basic && | |
3ac8f630 | 173 | git ls-remote src refs/heads/main >expect && |
d887cc18 JH |
174 | ( |
175 | cd dst && | |
3ac8f630 | 176 | test_must_fail git push --force-with-lease=main:main^ origin :main |
d887cc18 | 177 | ) && |
3ac8f630 | 178 | git ls-remote src refs/heads/main >actual && |
d887cc18 JH |
179 | test_cmp expect actual |
180 | ' | |
181 | ||
182 | test_expect_success 'push to delete (protected, forced)' ' | |
183 | setup_srcdst_basic && | |
184 | ( | |
185 | cd dst && | |
3ac8f630 | 186 | git push --force --force-with-lease=main:main^ origin :main |
d887cc18 | 187 | ) && |
3ac8f630 | 188 | git ls-remote src refs/heads/main >actual && |
d3c6751b | 189 | test_must_be_empty actual |
d887cc18 JH |
190 | ' |
191 | ||
192 | test_expect_success 'push to delete (allowed)' ' | |
193 | setup_srcdst_basic && | |
194 | ( | |
195 | cd dst && | |
3ac8f630 | 196 | git push --force-with-lease=main origin :main 2>err && |
b2e93f88 | 197 | grep deleted err |
d887cc18 | 198 | ) && |
3ac8f630 | 199 | git ls-remote src refs/heads/main >actual && |
d3c6751b | 200 | test_must_be_empty actual |
d887cc18 JH |
201 | ' |
202 | ||
203 | test_expect_success 'cover everything with default force-with-lease (protected)' ' | |
204 | setup_srcdst_basic && | |
205 | ( | |
206 | cd src && | |
3ac8f630 | 207 | git branch nain main^ |
99094a7a | 208 | ) && |
d887cc18 JH |
209 | git ls-remote src refs/heads/\* >expect && |
210 | ( | |
211 | cd dst && | |
3ac8f630 | 212 | test_must_fail git push --force-with-lease origin main main:nain |
d887cc18 JH |
213 | ) && |
214 | git ls-remote src refs/heads/\* >actual && | |
215 | test_cmp expect actual | |
216 | ' | |
217 | ||
218 | test_expect_success 'cover everything with default force-with-lease (allowed)' ' | |
219 | setup_srcdst_basic && | |
220 | ( | |
221 | cd src && | |
3ac8f630 | 222 | git branch nain main^ |
99094a7a | 223 | ) && |
d887cc18 JH |
224 | ( |
225 | cd dst && | |
226 | git fetch && | |
3ac8f630 | 227 | git push --force-with-lease origin main main:nain |
d887cc18 | 228 | ) && |
3ac8f630 JS |
229 | git ls-remote dst refs/heads/main | |
230 | sed -e "s/main/nain/" >expect && | |
231 | git ls-remote src refs/heads/nain >actual && | |
d887cc18 JH |
232 | test_cmp expect actual |
233 | ' | |
234 | ||
64ac39af JK |
235 | test_expect_success 'new branch covered by force-with-lease' ' |
236 | setup_srcdst_basic && | |
237 | ( | |
238 | cd dst && | |
3ac8f630 | 239 | git branch branch main && |
64ac39af JK |
240 | git push --force-with-lease=branch origin branch |
241 | ) && | |
242 | git ls-remote dst refs/heads/branch >expect && | |
243 | git ls-remote src refs/heads/branch >actual && | |
244 | test_cmp expect actual | |
245 | ' | |
246 | ||
eee98e74 JK |
247 | test_expect_success 'new branch covered by force-with-lease (explicit)' ' |
248 | setup_srcdst_basic && | |
249 | ( | |
250 | cd dst && | |
3ac8f630 | 251 | git branch branch main && |
eee98e74 JK |
252 | git push --force-with-lease=branch: origin branch |
253 | ) && | |
254 | git ls-remote dst refs/heads/branch >expect && | |
255 | git ls-remote src refs/heads/branch >actual && | |
256 | test_cmp expect actual | |
257 | ' | |
258 | ||
259 | test_expect_success 'new branch already exists' ' | |
260 | setup_srcdst_basic && | |
261 | ( | |
262 | cd src && | |
3ac8f630 | 263 | git checkout -b branch main && |
9eed4f37 | 264 | test_commit F |
eee98e74 JK |
265 | ) && |
266 | ( | |
267 | cd dst && | |
3ac8f630 | 268 | git branch branch main && |
eee98e74 JK |
269 | test_must_fail git push --force-with-lease=branch: origin branch |
270 | ) | |
271 | ' | |
272 | ||
f17d642d ÆAB |
273 | test_expect_success 'background updates of REMOTE can be mitigated with a non-updated REMOTE-push' ' |
274 | rm -rf src dst && | |
275 | git init --bare src.bare && | |
276 | test_when_finished "rm -rf src.bare" && | |
277 | git clone --no-local src.bare dst && | |
278 | test_when_finished "rm -rf dst" && | |
279 | ( | |
280 | cd dst && | |
281 | test_commit G && | |
282 | git remote add origin-push ../src.bare && | |
3ac8f630 | 283 | git push origin-push main:main |
f17d642d ÆAB |
284 | ) && |
285 | git clone --no-local src.bare dst2 && | |
286 | test_when_finished "rm -rf dst2" && | |
287 | ( | |
288 | cd dst2 && | |
289 | test_commit H && | |
290 | git push | |
291 | ) && | |
292 | ( | |
293 | cd dst && | |
294 | test_commit I && | |
295 | git fetch origin && | |
296 | test_must_fail git push --force-with-lease origin-push && | |
297 | git fetch origin-push && | |
298 | git push --force-with-lease origin-push | |
299 | ) | |
300 | ' | |
301 | ||
3b5bf965 SK |
302 | test_expect_success 'background updates to remote can be mitigated with "--force-if-includes"' ' |
303 | setup_src_dup_dst && | |
304 | test_when_finished "rm -fr dst src dup" && | |
3ac8f630 | 305 | git ls-remote dst refs/heads/main >expect.main && |
3b5bf965 SK |
306 | git ls-remote dst refs/heads/branch >expect.branch && |
307 | ( | |
308 | cd src && | |
309 | git switch branch && | |
310 | test_commit I && | |
3ac8f630 | 311 | git switch main && |
3b5bf965 SK |
312 | test_commit J && |
313 | git fetch --all && | |
314 | test_must_fail git push --force-with-lease --force-if-includes --all | |
315 | ) && | |
3ac8f630 | 316 | git ls-remote dst refs/heads/main >actual.main && |
3b5bf965 | 317 | git ls-remote dst refs/heads/branch >actual.branch && |
3ac8f630 | 318 | test_cmp expect.main actual.main && |
3b5bf965 SK |
319 | test_cmp expect.branch actual.branch |
320 | ' | |
321 | ||
322 | test_expect_success 'background updates to remote can be mitigated with "push.useForceIfIncludes"' ' | |
323 | setup_src_dup_dst && | |
324 | test_when_finished "rm -fr dst src dup" && | |
3ac8f630 | 325 | git ls-remote dst refs/heads/main >expect.main && |
3b5bf965 SK |
326 | ( |
327 | cd src && | |
328 | git switch branch && | |
329 | test_commit I && | |
3ac8f630 | 330 | git switch main && |
3b5bf965 SK |
331 | test_commit J && |
332 | git fetch --all && | |
333 | git config --local push.useForceIfIncludes true && | |
3ac8f630 | 334 | test_must_fail git push --force-with-lease=main origin main |
3b5bf965 | 335 | ) && |
3ac8f630 JS |
336 | git ls-remote dst refs/heads/main >actual.main && |
337 | test_cmp expect.main actual.main | |
3b5bf965 SK |
338 | ' |
339 | ||
340 | test_expect_success '"--force-if-includes" should be disabled for --force-with-lease="<refname>:<expect>"' ' | |
341 | setup_src_dup_dst && | |
342 | test_when_finished "rm -fr dst src dup" && | |
3ac8f630 | 343 | git ls-remote dst refs/heads/main >expect.main && |
3b5bf965 SK |
344 | ( |
345 | cd src && | |
346 | git switch branch && | |
347 | test_commit I && | |
3ac8f630 | 348 | git switch main && |
3b5bf965 | 349 | test_commit J && |
3ac8f630 | 350 | remote_head="$(git rev-parse refs/remotes/origin/main)" && |
3b5bf965 | 351 | git fetch --all && |
3ac8f630 | 352 | test_must_fail git push --force-if-includes --force-with-lease="main:$remote_head" 2>err && |
3b5bf965 SK |
353 | grep "stale info" err |
354 | ) && | |
3ac8f630 JS |
355 | git ls-remote dst refs/heads/main >actual.main && |
356 | test_cmp expect.main actual.main | |
3b5bf965 SK |
357 | ' |
358 | ||
359 | test_expect_success '"--force-if-includes" should allow forced update after a rebase ("pull --rebase")' ' | |
360 | setup_src_dup_dst && | |
361 | test_when_finished "rm -fr dst src dup" && | |
362 | ( | |
363 | cd src && | |
364 | git switch branch && | |
365 | test_commit I && | |
3ac8f630 | 366 | git switch main && |
3b5bf965 | 367 | test_commit J && |
3ac8f630 JS |
368 | git pull --rebase origin main && |
369 | git push --force-if-includes --force-with-lease="main" | |
3b5bf965 SK |
370 | ) |
371 | ' | |
372 | ||
373 | test_expect_success '"--force-if-includes" should allow forced update after a rebase ("pull --rebase", local rebase)' ' | |
374 | setup_src_dup_dst && | |
375 | test_when_finished "rm -fr dst src dup" && | |
376 | ( | |
377 | cd src && | |
378 | git switch branch && | |
379 | test_commit I && | |
3ac8f630 | 380 | git switch main && |
3b5bf965 | 381 | test_commit J && |
3ac8f630 | 382 | git pull --rebase origin main && |
3b5bf965 | 383 | git rebase --onto HEAD~4 HEAD~1 && |
3ac8f630 | 384 | git push --force-if-includes --force-with-lease="main" |
3b5bf965 SK |
385 | ) |
386 | ' | |
387 | ||
388 | test_expect_success '"--force-if-includes" should allow deletes' ' | |
389 | setup_src_dup_dst && | |
390 | test_when_finished "rm -fr dst src dup" && | |
391 | ( | |
392 | cd src && | |
393 | git switch branch && | |
394 | git pull --rebase origin branch && | |
395 | git push --force-if-includes --force-with-lease="branch" origin :branch | |
396 | ) | |
397 | ' | |
398 | ||
d887cc18 | 399 | test_done |