]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5533-push-cas.sh
The third batch
[thirdparty/git.git] / t / t5533-push-cas.sh
CommitLineData
d887cc18
JH
1#!/bin/sh
2
3test_description='compare & swap push force/delete safety'
4
3ac8f630 5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
d887cc18
JH
8. ./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
3b5bf965
SK
19# 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 &&
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 59test_expect_success setup '
53350a35 60 # create template repository
d887cc18
JH
61 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 &&
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
79test_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
92test_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
113test_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
132test_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
144test_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
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 &&
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
171test_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
182test_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
192test_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
203test_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
218test_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
235test_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
247test_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
259test_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
273test_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
302test_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
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" &&
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
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" &&
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
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 &&
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
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 &&
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
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
d887cc18 399test_done