]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5533-push-cas.sh
The third batch
[thirdparty/git.git] / t / t5533-push-cas.sh
1 #!/bin/sh
2
3 test_description='compare & swap push force/delete safety'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
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
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 &&
35 git merge origin/main &&
36 git switch -c branch main~2 &&
37 test_commit D &&
38 test_commit E &&
39 git push origin --all
40 ) &&
41 (
42 cd src &&
43 git switch main &&
44 git fetch --all &&
45 git branch branch --track origin/branch &&
46 git rebase origin/main
47 ) &&
48 (
49 cd dup &&
50 git switch main &&
51 test_commit F &&
52 test_commit G &&
53 git switch branch &&
54 test_commit H &&
55 git push origin --all
56 )
57 }
58
59 test_expect_success setup '
60 # create template repository
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 &&
71 test_must_fail git push --force-with-lease=main:main origin main 2>err &&
72 grep "stale info" err
73 ) &&
74 git ls-remote . refs/heads/main >expect &&
75 git ls-remote src refs/heads/main >actual &&
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 &&
84 git push --force --force-with-lease=main:main origin main 2>err &&
85 grep "forced update" err
86 ) &&
87 git ls-remote dst refs/heads/main >expect &&
88 git ls-remote src refs/heads/main >actual &&
89 test_cmp expect actual
90 '
91
92 test_expect_success 'push to update (protected, tracking)' '
93 setup_srcdst_basic &&
94 (
95 cd src &&
96 git checkout main &&
97 test_commit D &&
98 git checkout HEAD^0
99 ) &&
100 git ls-remote src refs/heads/main >expect &&
101 (
102 cd dst &&
103 test_commit E &&
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 &&
107 test_cmp expect actual
108 ) &&
109 git ls-remote src refs/heads/main >actual &&
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 &&
117 git checkout main &&
118 test_commit D &&
119 git checkout HEAD^0
120 ) &&
121 (
122 cd dst &&
123 test_commit E &&
124 git ls-remote . refs/remotes/origin/main >expect &&
125 git push --force --force-with-lease=main origin main
126 ) &&
127 git ls-remote dst refs/heads/main >expect &&
128 git ls-remote src refs/heads/main >actual &&
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 &&
137 git push --force-with-lease=main:main^ origin main
138 ) &&
139 git ls-remote dst refs/heads/main >expect &&
140 git ls-remote src refs/heads/main >actual &&
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 &&
149 git push --force-with-lease=main origin main 2>err &&
150 ! grep "forced update" err
151 ) &&
152 git ls-remote dst refs/heads/main >expect &&
153 git ls-remote src refs/heads/main >actual &&
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 &&
163 git push --force-with-lease=main origin main 2>err &&
164 grep "forced update" err
165 ) &&
166 git ls-remote dst refs/heads/main >expect &&
167 git ls-remote src refs/heads/main >actual &&
168 test_cmp expect actual
169 '
170
171 test_expect_success 'push to delete (protected)' '
172 setup_srcdst_basic &&
173 git ls-remote src refs/heads/main >expect &&
174 (
175 cd dst &&
176 test_must_fail git push --force-with-lease=main:main^ origin :main
177 ) &&
178 git ls-remote src refs/heads/main >actual &&
179 test_cmp expect actual
180 '
181
182 test_expect_success 'push to delete (protected, forced)' '
183 setup_srcdst_basic &&
184 (
185 cd dst &&
186 git push --force --force-with-lease=main:main^ origin :main
187 ) &&
188 git ls-remote src refs/heads/main >actual &&
189 test_must_be_empty actual
190 '
191
192 test_expect_success 'push to delete (allowed)' '
193 setup_srcdst_basic &&
194 (
195 cd dst &&
196 git push --force-with-lease=main origin :main 2>err &&
197 grep deleted err
198 ) &&
199 git ls-remote src refs/heads/main >actual &&
200 test_must_be_empty actual
201 '
202
203 test_expect_success 'cover everything with default force-with-lease (protected)' '
204 setup_srcdst_basic &&
205 (
206 cd src &&
207 git branch nain main^
208 ) &&
209 git ls-remote src refs/heads/\* >expect &&
210 (
211 cd dst &&
212 test_must_fail git push --force-with-lease origin main main:nain
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 &&
222 git branch nain main^
223 ) &&
224 (
225 cd dst &&
226 git fetch &&
227 git push --force-with-lease origin main main:nain
228 ) &&
229 git ls-remote dst refs/heads/main |
230 sed -e "s/main/nain/" >expect &&
231 git ls-remote src refs/heads/nain >actual &&
232 test_cmp expect actual
233 '
234
235 test_expect_success 'new branch covered by force-with-lease' '
236 setup_srcdst_basic &&
237 (
238 cd dst &&
239 git branch branch main &&
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
247 test_expect_success 'new branch covered by force-with-lease (explicit)' '
248 setup_srcdst_basic &&
249 (
250 cd dst &&
251 git branch branch main &&
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 &&
263 git checkout -b branch main &&
264 test_commit F
265 ) &&
266 (
267 cd dst &&
268 git branch branch main &&
269 test_must_fail git push --force-with-lease=branch: origin branch
270 )
271 '
272
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 &&
283 git push origin-push main:main
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
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" &&
305 git ls-remote dst refs/heads/main >expect.main &&
306 git ls-remote dst refs/heads/branch >expect.branch &&
307 (
308 cd src &&
309 git switch branch &&
310 test_commit I &&
311 git switch main &&
312 test_commit J &&
313 git fetch --all &&
314 test_must_fail git push --force-with-lease --force-if-includes --all
315 ) &&
316 git ls-remote dst refs/heads/main >actual.main &&
317 git ls-remote dst refs/heads/branch >actual.branch &&
318 test_cmp expect.main actual.main &&
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" &&
325 git ls-remote dst refs/heads/main >expect.main &&
326 (
327 cd src &&
328 git switch branch &&
329 test_commit I &&
330 git switch main &&
331 test_commit J &&
332 git fetch --all &&
333 git config --local push.useForceIfIncludes true &&
334 test_must_fail git push --force-with-lease=main origin main
335 ) &&
336 git ls-remote dst refs/heads/main >actual.main &&
337 test_cmp expect.main actual.main
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" &&
343 git ls-remote dst refs/heads/main >expect.main &&
344 (
345 cd src &&
346 git switch branch &&
347 test_commit I &&
348 git switch main &&
349 test_commit J &&
350 remote_head="$(git rev-parse refs/remotes/origin/main)" &&
351 git fetch --all &&
352 test_must_fail git push --force-if-includes --force-with-lease="main:$remote_head" 2>err &&
353 grep "stale info" err
354 ) &&
355 git ls-remote dst refs/heads/main >actual.main &&
356 test_cmp expect.main actual.main
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 &&
366 git switch main &&
367 test_commit J &&
368 git pull --rebase origin main &&
369 git push --force-if-includes --force-with-lease="main"
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 &&
380 git switch main &&
381 test_commit J &&
382 git pull --rebase origin main &&
383 git rebase --onto HEAD~4 HEAD~1 &&
384 git push --force-if-includes --force-with-lease="main"
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
399 test_done