blob: cba26a872dde465c01cd99782029811cf2da9acf [file] [log] [blame]
Junio C Hamanod887cc12013-07-09 12:09:28 -07001#!/bin/sh
2
3test_description='compare & swap push force/delete safety'
4
Johannes Schindelin3ac8f632020-11-18 23:44:33 +00005GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
Johannes Schindelin334afbc2020-11-18 23:44:19 +00006export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
Junio C Hamanod887cc12013-07-09 12:09:28 -07008. ./test-lib.sh
9
10setup_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
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +053019# For tests with "--force-if-includes".
20setup_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 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000035 git merge origin/main &&
36 git switch -c branch main~2 &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +053037 test_commit D &&
38 test_commit E &&
39 git push origin --all
40 ) &&
41 (
42 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000043 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +053044 git fetch --all &&
45 git branch branch --track origin/branch &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000046 git rebase origin/main
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +053047 ) &&
48 (
49 cd dup &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000050 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +053051 test_commit F &&
52 test_commit G &&
53 git switch branch &&
54 test_commit H &&
55 git push origin --all
56 )
57}
58
Junio C Hamanod887cc12013-07-09 12:09:28 -070059test_expect_success setup '
Jeff King53350a32015-03-20 06:12:37 -040060 # create template repository
Junio C Hamanod887cc12013-07-09 12:09:28 -070061 test_commit A &&
62 test_commit B &&
63 test_commit C
64'
65
66test_expect_success 'push to update (protected)' '
67 setup_srcdst_basic &&
68 (
69 cd dst &&
70 test_commit D &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000071 test_must_fail git push --force-with-lease=main:main origin main 2>err &&
Andrew Wheelerb2e93f82016-01-29 17:18:42 -060072 grep "stale info" err
Junio C Hamanod887cc12013-07-09 12:09:28 -070073 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000074 git ls-remote . refs/heads/main >expect &&
75 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -070076 test_cmp expect actual
77'
78
79test_expect_success 'push to update (protected, forced)' '
80 setup_srcdst_basic &&
81 (
82 cd dst &&
83 test_commit D &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000084 git push --force --force-with-lease=main:main origin main 2>err &&
Andrew Wheelerb2e93f82016-01-29 17:18:42 -060085 grep "forced update" err
Junio C Hamanod887cc12013-07-09 12:09:28 -070086 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000087 git ls-remote dst refs/heads/main >expect &&
88 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -070089 test_cmp expect actual
90'
91
92test_expect_success 'push to update (protected, tracking)' '
93 setup_srcdst_basic &&
94 (
95 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +000096 git checkout main &&
Junio C Hamanod887cc12013-07-09 12:09:28 -070097 test_commit D &&
98 git checkout HEAD^0
99 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000100 git ls-remote src refs/heads/main >expect &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700101 (
102 cd dst &&
103 test_commit E &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000104 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 &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700107 test_cmp expect actual
108 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000109 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700110 test_cmp expect actual
111'
112
113test_expect_success 'push to update (protected, tracking, forced)' '
114 setup_srcdst_basic &&
115 (
116 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000117 git checkout main &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700118 test_commit D &&
119 git checkout HEAD^0
120 ) &&
121 (
122 cd dst &&
123 test_commit E &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000124 git ls-remote . refs/remotes/origin/main >expect &&
125 git push --force --force-with-lease=main origin main
Junio C Hamanod887cc12013-07-09 12:09:28 -0700126 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000127 git ls-remote dst refs/heads/main >expect &&
128 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700129 test_cmp expect actual
130'
131
132test_expect_success 'push to update (allowed)' '
133 setup_srcdst_basic &&
134 (
135 cd dst &&
136 test_commit D &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000137 git push --force-with-lease=main:main^ origin main
Junio C Hamanod887cc12013-07-09 12:09:28 -0700138 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000139 git ls-remote dst refs/heads/main >expect &&
140 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700141 test_cmp expect actual
142'
143
144test_expect_success 'push to update (allowed, tracking)' '
145 setup_srcdst_basic &&
146 (
147 cd dst &&
148 test_commit D &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000149 git push --force-with-lease=main origin main 2>err &&
Andrew Wheelerb2e93f82016-01-29 17:18:42 -0600150 ! grep "forced update" err
Junio C Hamanod887cc12013-07-09 12:09:28 -0700151 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000152 git ls-remote dst refs/heads/main >expect &&
153 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700154 test_cmp expect actual
155'
156
157test_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 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000163 git push --force-with-lease=main origin main 2>err &&
Andrew Wheelerb2e93f82016-01-29 17:18:42 -0600164 grep "forced update" err
Junio C Hamanod887cc12013-07-09 12:09:28 -0700165 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000166 git ls-remote dst refs/heads/main >expect &&
167 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700168 test_cmp expect actual
169'
170
171test_expect_success 'push to delete (protected)' '
172 setup_srcdst_basic &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000173 git ls-remote src refs/heads/main >expect &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700174 (
175 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000176 test_must_fail git push --force-with-lease=main:main^ origin :main
Junio C Hamanod887cc12013-07-09 12:09:28 -0700177 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000178 git ls-remote src refs/heads/main >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700179 test_cmp expect actual
180'
181
182test_expect_success 'push to delete (protected, forced)' '
183 setup_srcdst_basic &&
184 (
185 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000186 git push --force --force-with-lease=main:main^ origin :main
Junio C Hamanod887cc12013-07-09 12:09:28 -0700187 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000188 git ls-remote src refs/heads/main >actual &&
Ævar Arnfjörð Bjarmasond3c67512018-07-27 17:48:11 +0000189 test_must_be_empty actual
Junio C Hamanod887cc12013-07-09 12:09:28 -0700190'
191
192test_expect_success 'push to delete (allowed)' '
193 setup_srcdst_basic &&
194 (
195 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000196 git push --force-with-lease=main origin :main 2>err &&
Andrew Wheelerb2e93f82016-01-29 17:18:42 -0600197 grep deleted err
Junio C Hamanod887cc12013-07-09 12:09:28 -0700198 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000199 git ls-remote src refs/heads/main >actual &&
Ævar Arnfjörð Bjarmasond3c67512018-07-27 17:48:11 +0000200 test_must_be_empty actual
Junio C Hamanod887cc12013-07-09 12:09:28 -0700201'
202
203test_expect_success 'cover everything with default force-with-lease (protected)' '
204 setup_srcdst_basic &&
205 (
206 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000207 git branch nain main^
Jeff King99094a72015-03-20 06:07:15 -0400208 ) &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700209 git ls-remote src refs/heads/\* >expect &&
210 (
211 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000212 test_must_fail git push --force-with-lease origin main main:nain
Junio C Hamanod887cc12013-07-09 12:09:28 -0700213 ) &&
214 git ls-remote src refs/heads/\* >actual &&
215 test_cmp expect actual
216'
217
218test_expect_success 'cover everything with default force-with-lease (allowed)' '
219 setup_srcdst_basic &&
220 (
221 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000222 git branch nain main^
Jeff King99094a72015-03-20 06:07:15 -0400223 ) &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700224 (
225 cd dst &&
226 git fetch &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000227 git push --force-with-lease origin main main:nain
Junio C Hamanod887cc12013-07-09 12:09:28 -0700228 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000229 git ls-remote dst refs/heads/main |
230 sed -e "s/main/nain/" >expect &&
231 git ls-remote src refs/heads/nain >actual &&
Junio C Hamanod887cc12013-07-09 12:09:28 -0700232 test_cmp expect actual
233'
234
John Keeping64ac39a2016-07-26 21:44:45 +0100235test_expect_success 'new branch covered by force-with-lease' '
236 setup_srcdst_basic &&
237 (
238 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000239 git branch branch main &&
John Keeping64ac39a2016-07-26 21:44:45 +0100240 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
John Keepingeee98e72016-07-26 21:44:44 +0100247test_expect_success 'new branch covered by force-with-lease (explicit)' '
248 setup_srcdst_basic &&
249 (
250 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000251 git branch branch main &&
John Keepingeee98e72016-07-26 21:44:44 +0100252 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
259test_expect_success 'new branch already exists' '
260 setup_srcdst_basic &&
261 (
262 cd src &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000263 git checkout -b branch main &&
Johannes Schindelin9eed4f32016-08-04 16:54:35 +0200264 test_commit F
John Keepingeee98e72016-07-26 21:44:44 +0100265 ) &&
266 (
267 cd dst &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000268 git branch branch main &&
John Keepingeee98e72016-07-26 21:44:44 +0100269 test_must_fail git push --force-with-lease=branch: origin branch
270 )
271'
272
Ævar Arnfjörð Bjarmasonf17d6422017-04-19 09:22:03 +0000273test_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 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000283 git push origin-push main:main
Ævar Arnfjörð Bjarmasonf17d6422017-04-19 09:22:03 +0000284 ) &&
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
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530302test_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" &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000305 git ls-remote dst refs/heads/main >expect.main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530306 git ls-remote dst refs/heads/branch >expect.branch &&
307 (
308 cd src &&
309 git switch branch &&
310 test_commit I &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000311 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530312 test_commit J &&
313 git fetch --all &&
314 test_must_fail git push --force-with-lease --force-if-includes --all
315 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000316 git ls-remote dst refs/heads/main >actual.main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530317 git ls-remote dst refs/heads/branch >actual.branch &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000318 test_cmp expect.main actual.main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530319 test_cmp expect.branch actual.branch
320'
321
322test_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" &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000325 git ls-remote dst refs/heads/main >expect.main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530326 (
327 cd src &&
328 git switch branch &&
329 test_commit I &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000330 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530331 test_commit J &&
332 git fetch --all &&
333 git config --local push.useForceIfIncludes true &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000334 test_must_fail git push --force-with-lease=main origin main
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530335 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000336 git ls-remote dst refs/heads/main >actual.main &&
337 test_cmp expect.main actual.main
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530338'
339
340test_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" &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000343 git ls-remote dst refs/heads/main >expect.main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530344 (
345 cd src &&
346 git switch branch &&
347 test_commit I &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000348 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530349 test_commit J &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000350 remote_head="$(git rev-parse refs/remotes/origin/main)" &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530351 git fetch --all &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000352 test_must_fail git push --force-if-includes --force-with-lease="main:$remote_head" 2>err &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530353 grep "stale info" err
354 ) &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000355 git ls-remote dst refs/heads/main >actual.main &&
356 test_cmp expect.main actual.main
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530357'
358
359test_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 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000366 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530367 test_commit J &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000368 git pull --rebase origin main &&
369 git push --force-if-includes --force-with-lease="main"
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530370 )
371'
372
373test_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 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000380 git switch main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530381 test_commit J &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000382 git pull --rebase origin main &&
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530383 git rebase --onto HEAD~4 HEAD~1 &&
Johannes Schindelin3ac8f632020-11-18 23:44:33 +0000384 git push --force-if-includes --force-with-lease="main"
Srinidhi Kaushik3b5bf962020-10-03 17:40:46 +0530385 )
386'
387
388test_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
Junio C Hamanod887cc12013-07-09 12:09:28 -0700399test_done