3 test_description
='compare & swap push force/delete safety'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=master
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 setup_srcdst_basic
() {
12 git clone
--no-local . src
&&
13 git clone
--no-local src dst
&&
15 cd src
&& git checkout HEAD^
0
19 # For tests with "--force-if-includes".
20 setup_src_dup_dst
() {
22 git init
--bare dst
&&
23 git clone
--no-local dst src
&&
24 git clone
--no-local dst dup
35 git merge origin
/master
&&
36 git switch
-c branch master~
2 &&
45 git branch branch
--track origin
/branch
&&
46 git rebase origin
/master
59 test_expect_success setup
'
60 # create template repository
66 test_expect_success
'push to update (protected)' '
71 test_must_fail git push --force-with-lease=master:master origin master 2>err &&
74 git ls-remote . refs/heads/master >expect &&
75 git ls-remote src refs/heads/master >actual &&
76 test_cmp expect actual
79 test_expect_success
'push to update (protected, forced)' '
84 git push --force --force-with-lease=master:master origin master 2>err &&
85 grep "forced update" err
87 git ls-remote dst refs/heads/master >expect &&
88 git ls-remote src refs/heads/master >actual &&
89 test_cmp expect actual
92 test_expect_success
'push to update (protected, tracking)' '
96 git checkout master &&
100 git ls-remote src refs/heads/master >expect &&
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
109 git ls-remote src refs/heads/master >actual &&
110 test_cmp expect actual
113 test_expect_success
'push to update (protected, tracking, forced)' '
114 setup_srcdst_basic &&
117 git checkout master &&
124 git ls-remote . refs/remotes/origin/master >expect &&
125 git push --force --force-with-lease=master origin master
127 git ls-remote dst refs/heads/master >expect &&
128 git ls-remote src refs/heads/master >actual &&
129 test_cmp expect actual
132 test_expect_success
'push to update (allowed)' '
133 setup_srcdst_basic &&
137 git push --force-with-lease=master:master^ origin master
139 git ls-remote dst refs/heads/master >expect &&
140 git ls-remote src refs/heads/master >actual &&
141 test_cmp expect actual
144 test_expect_success
'push to update (allowed, tracking)' '
145 setup_srcdst_basic &&
149 git push --force-with-lease=master origin master 2>err &&
150 ! grep "forced update" err
152 git ls-remote dst refs/heads/master >expect &&
153 git ls-remote src refs/heads/master >actual &&
154 test_cmp expect actual
157 test_expect_success
'push to update (allowed even though no-ff)' '
158 setup_srcdst_basic &&
161 git reset --hard HEAD^ &&
163 git push --force-with-lease=master origin master 2>err &&
164 grep "forced update" err
166 git ls-remote dst refs/heads/master >expect &&
167 git ls-remote src refs/heads/master >actual &&
168 test_cmp expect actual
171 test_expect_success
'push to delete (protected)' '
172 setup_srcdst_basic &&
173 git ls-remote src refs/heads/master >expect &&
176 test_must_fail git push --force-with-lease=master:master^ origin :master
178 git ls-remote src refs/heads/master >actual &&
179 test_cmp expect actual
182 test_expect_success
'push to delete (protected, forced)' '
183 setup_srcdst_basic &&
186 git push --force --force-with-lease=master:master^ origin :master
188 git ls-remote src refs/heads/master >actual &&
189 test_must_be_empty actual
192 test_expect_success
'push to delete (allowed)' '
193 setup_srcdst_basic &&
196 git push --force-with-lease=master origin :master 2>err &&
199 git ls-remote src refs/heads/master >actual &&
200 test_must_be_empty actual
203 test_expect_success
'cover everything with default force-with-lease (protected)' '
204 setup_srcdst_basic &&
207 git branch naster master^
209 git ls-remote src refs/heads/\* >expect &&
212 test_must_fail git push --force-with-lease origin master master:naster
214 git ls-remote src refs/heads/\* >actual &&
215 test_cmp expect actual
218 test_expect_success
'cover everything with default force-with-lease (allowed)' '
219 setup_srcdst_basic &&
222 git branch naster master^
227 git push --force-with-lease origin master master:naster
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
235 test_expect_success
'new branch covered by force-with-lease' '
236 setup_srcdst_basic &&
239 git branch branch master &&
240 git push --force-with-lease=branch origin branch
242 git ls-remote dst refs/heads/branch >expect &&
243 git ls-remote src refs/heads/branch >actual &&
244 test_cmp expect actual
247 test_expect_success
'new branch covered by force-with-lease (explicit)' '
248 setup_srcdst_basic &&
251 git branch branch master &&
252 git push --force-with-lease=branch: origin branch
254 git ls-remote dst refs/heads/branch >expect &&
255 git ls-remote src refs/heads/branch >actual &&
256 test_cmp expect actual
259 test_expect_success
'new branch already exists' '
260 setup_srcdst_basic &&
263 git checkout -b branch master &&
268 git branch branch master &&
269 test_must_fail git push --force-with-lease=branch: origin branch
273 test_expect_success
'background updates of REMOTE can be mitigated with a non-updated REMOTE-push' '
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" &&
282 git remote add origin-push ../src.bare &&
283 git push origin-push master:master
285 git clone --no-local src.bare dst2 &&
286 test_when_finished "rm -rf dst2" &&
296 test_must_fail git push --force-with-lease origin-push &&
297 git fetch origin-push &&
298 git push --force-with-lease origin-push
302 test_expect_success
'background updates to remote can be mitigated with "--force-if-includes"' '
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 &&
314 test_must_fail git push --force-with-lease --force-if-includes --all
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
322 test_expect_success
'background updates to remote can be mitigated with "push.useForceIfIncludes"' '
324 test_when_finished "rm -fr dst src dup" &&
325 git ls-remote dst refs/heads/master >expect.master &&
333 git config --local push.useForceIfIncludes true &&
334 test_must_fail git push --force-with-lease=master origin master
336 git ls-remote dst refs/heads/master >actual.master &&
337 test_cmp expect.master actual.master
340 test_expect_success
'"--force-if-includes" should be disabled for --force-with-lease="<refname>:<expect>"' '
342 test_when_finished "rm -fr dst src dup" &&
343 git ls-remote dst refs/heads/master >expect.master &&
350 remote_head="$(git rev-parse refs/remotes/origin/master)" &&
352 test_must_fail git push --force-if-includes --force-with-lease="master:$remote_head" 2>err &&
353 grep "stale info" err
355 git ls-remote dst refs/heads/master >actual.master &&
356 test_cmp expect.master actual.master
359 test_expect_success
'"--force-if-includes" should allow forced update after a rebase ("pull --rebase")' '
361 test_when_finished "rm -fr dst src dup" &&
368 git pull --rebase origin master &&
369 git push --force-if-includes --force-with-lease="master"
373 test_expect_success
'"--force-if-includes" should allow forced update after a rebase ("pull --rebase", local rebase)' '
375 test_when_finished "rm -fr dst src dup" &&
382 git pull --rebase origin master &&
383 git rebase --onto HEAD~4 HEAD~1 &&
384 git push --force-if-includes --force-with-lease="master"
388 test_expect_success
'"--force-if-includes" should allow deletes' '
390 test_when_finished "rm -fr dst src dup" &&
394 git pull --rebase origin branch &&
395 git push --force-if-includes --force-with-lease="branch" origin :branch