]>
Commit | Line | Data |
---|---|---|
d887cc18 JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='compare & swap push force/delete safety' | |
4 | ||
334afbc7 JS |
5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master |
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 && | |
35 | git merge origin/master && | |
36 | git switch -c branch master~2 && | |
37 | test_commit D && | |
38 | test_commit E && | |
39 | git push origin --all | |
40 | ) && | |
41 | ( | |
42 | cd src && | |
43 | git switch master && | |
44 | git fetch --all && | |
45 | git branch branch --track origin/branch && | |
46 | git rebase origin/master | |
47 | ) && | |
48 | ( | |
49 | cd dup && | |
50 | git switch master && | |
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 && | |
b2e93f88 AW |
71 | test_must_fail git push --force-with-lease=master:master origin master 2>err && |
72 | grep "stale info" err | |
d887cc18 JH |
73 | ) && |
74 | git ls-remote . refs/heads/master >expect && | |
75 | git ls-remote src refs/heads/master >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 && | |
b2e93f88 AW |
84 | git push --force --force-with-lease=master:master origin master 2>err && |
85 | grep "forced update" err | |
d887cc18 JH |
86 | ) && |
87 | git ls-remote dst refs/heads/master >expect && | |
88 | git ls-remote src refs/heads/master >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 master && | |
97 | test_commit D && | |
98 | git checkout HEAD^0 | |
99 | ) && | |
100 | git ls-remote src refs/heads/master >expect && | |
101 | ( | |
102 | cd dst && | |
103 | test_commit E && | |
104 | git ls-remote . refs/remotes/origin/master >expect && | |
105 | test_must_fail git push --force-with-lease=master origin master && | |
106 | git ls-remote . refs/remotes/origin/master >actual && | |
107 | test_cmp expect actual | |
108 | ) && | |
109 | git ls-remote src refs/heads/master >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 master && | |
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/master >expect && | |
125 | git push --force --force-with-lease=master origin master | |
126 | ) && | |
127 | git ls-remote dst refs/heads/master >expect && | |
128 | git ls-remote src refs/heads/master >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=master:master^ origin master | |
138 | ) && | |
139 | git ls-remote dst refs/heads/master >expect && | |
140 | git ls-remote src refs/heads/master >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 && | |
b2e93f88 AW |
149 | git push --force-with-lease=master origin master 2>err && |
150 | ! grep "forced update" err | |
d887cc18 JH |
151 | ) && |
152 | git ls-remote dst refs/heads/master >expect && | |
153 | git ls-remote src refs/heads/master >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 && | |
b2e93f88 AW |
163 | git push --force-with-lease=master origin master 2>err && |
164 | grep "forced update" err | |
d887cc18 JH |
165 | ) && |
166 | git ls-remote dst refs/heads/master >expect && | |
167 | git ls-remote src refs/heads/master >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/master >expect && | |
174 | ( | |
175 | cd dst && | |
176 | test_must_fail git push --force-with-lease=master:master^ origin :master | |
177 | ) && | |
178 | git ls-remote src refs/heads/master >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=master:master^ origin :master | |
187 | ) && | |
d887cc18 | 188 | git ls-remote src refs/heads/master >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 && | |
b2e93f88 AW |
196 | git push --force-with-lease=master origin :master 2>err && |
197 | grep deleted err | |
d887cc18 | 198 | ) && |
d887cc18 | 199 | git ls-remote src refs/heads/master >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 && | |
207 | git branch naster master^ | |
99094a7a | 208 | ) && |
d887cc18 JH |
209 | git ls-remote src refs/heads/\* >expect && |
210 | ( | |
211 | cd dst && | |
212 | test_must_fail git push --force-with-lease origin master master:naster | |
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 naster master^ | |
99094a7a | 223 | ) && |
d887cc18 JH |
224 | ( |
225 | cd dst && | |
226 | git fetch && | |
227 | git push --force-with-lease origin master master:naster | |
228 | ) && | |
229 | git ls-remote dst refs/heads/master | | |
230 | sed -e "s/master/naster/" >expect && | |
231 | git ls-remote src refs/heads/naster >actual && | |
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 && | |
239 | git branch branch master && | |
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 && | |
251 | git branch branch master && | |
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 master && | |
9eed4f37 | 264 | test_commit F |
eee98e74 JK |
265 | ) && |
266 | ( | |
267 | cd dst && | |
268 | git branch branch master && | |
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 && | |
283 | git push origin-push master:master | |
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" && | |
305 | git ls-remote dst refs/heads/master >expect.master && | |
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 master && | |
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/master >actual.master && | |
317 | git ls-remote dst refs/heads/branch >actual.branch && | |
318 | test_cmp expect.master actual.master && | |
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/master >expect.master && | |
326 | ( | |
327 | cd src && | |
328 | git switch branch && | |
329 | test_commit I && | |
330 | git switch master && | |
331 | test_commit J && | |
332 | git fetch --all && | |
333 | git config --local push.useForceIfIncludes true && | |
334 | test_must_fail git push --force-with-lease=master origin master | |
335 | ) && | |
336 | git ls-remote dst refs/heads/master >actual.master && | |
337 | test_cmp expect.master actual.master | |
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/master >expect.master && | |
344 | ( | |
345 | cd src && | |
346 | git switch branch && | |
347 | test_commit I && | |
348 | git switch master && | |
349 | test_commit J && | |
350 | remote_head="$(git rev-parse refs/remotes/origin/master)" && | |
351 | git fetch --all && | |
352 | test_must_fail git push --force-if-includes --force-with-lease="master:$remote_head" 2>err && | |
353 | grep "stale info" err | |
354 | ) && | |
355 | git ls-remote dst refs/heads/master >actual.master && | |
356 | test_cmp expect.master actual.master | |
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 master && | |
367 | test_commit J && | |
368 | git pull --rebase origin master && | |
369 | git push --force-if-includes --force-with-lease="master" | |
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 master && | |
381 | test_commit J && | |
382 | git pull --rebase origin master && | |
383 | git rebase --onto HEAD~4 HEAD~1 && | |
384 | git push --force-if-includes --force-with-lease="master" | |
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 |