Git 2.45
[git/gitster.git] / t / t5531-deep-submodule-push.sh
blobf3fff557447c3e2e5c46878e7f0415c38d29e970
1 #!/bin/sh
3 test_description='test push with submodules'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1
9 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
11 . ./test-lib.sh
13 test_expect_success setup '
14 mkdir pub.git &&
15 GIT_DIR=pub.git git init --bare &&
16 GIT_DIR=pub.git git config receive.fsckobjects true &&
17 mkdir work &&
19 cd work &&
20 git init &&
21 git config push.default matching &&
22 mkdir -p gar/bage &&
24 cd gar/bage &&
25 git init &&
26 git config push.default matching &&
27 >junk &&
28 git add junk &&
29 git commit -m "Initial junk"
30 ) &&
31 git add gar/bage &&
32 git commit -m "Initial superproject"
36 test_expect_success 'push works with recorded gitlink' '
38 cd work &&
39 git push ../pub.git main
43 test_expect_success 'push if submodule has no remote' '
45 cd work/gar/bage &&
46 >junk2 &&
47 git add junk2 &&
48 git commit -m "Second junk"
49 ) &&
51 cd work &&
52 git add gar/bage &&
53 git commit -m "Second commit for gar/bage" &&
54 git push --recurse-submodules=check ../pub.git main
58 test_expect_success 'push fails if submodule commit not on remote' '
60 cd work/gar &&
61 git clone --bare bage ../../submodule.git &&
62 cd bage &&
63 git remote add origin ../../../submodule.git &&
64 git fetch &&
65 >junk3 &&
66 git add junk3 &&
67 git commit -m "Third junk"
68 ) &&
70 cd work &&
71 git add gar/bage &&
72 git commit -m "Third commit for gar/bage" &&
73 # the push should fail with --recurse-submodules=check
74 # on the command line...
75 test_must_fail git push --recurse-submodules=check ../pub.git main &&
77 # ...or if specified in the configuration..
78 test_must_fail git -c push.recurseSubmodules=check push ../pub.git main
82 test_expect_success 'push succeeds after commit was pushed to remote' '
84 cd work/gar/bage &&
85 git push origin main
86 ) &&
88 cd work &&
89 git push --recurse-submodules=check ../pub.git main
93 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
95 cd work/gar/bage &&
96 >recurse-on-demand-on-command-line &&
97 git add recurse-on-demand-on-command-line &&
98 git commit -m "Recurse on-demand on command line junk"
99 ) &&
101 cd work &&
102 git add gar/bage &&
103 git commit -m "Recurse on-demand on command line for gar/bage" &&
104 git push --recurse-submodules=on-demand ../pub.git main &&
105 # Check that the supermodule commit got there
106 git fetch ../pub.git &&
107 git diff --quiet FETCH_HEAD main &&
108 # Check that the submodule commit got there too
109 cd gar/bage &&
110 git diff --quiet origin/main main
114 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
116 cd work/gar/bage &&
117 >recurse-on-demand-from-config &&
118 git add recurse-on-demand-from-config &&
119 git commit -m "Recurse on-demand from config junk"
120 ) &&
122 cd work &&
123 git add gar/bage &&
124 git commit -m "Recurse on-demand from config for gar/bage" &&
125 git -c push.recurseSubmodules=on-demand push ../pub.git main &&
126 # Check that the supermodule commit got there
127 git fetch ../pub.git &&
128 git diff --quiet FETCH_HEAD main &&
129 # Check that the submodule commit got there too
130 cd gar/bage &&
131 git diff --quiet origin/main main
135 test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
137 cd work/gar/bage &&
138 >recurse-on-demand-from-submodule-recurse-config &&
139 git add recurse-on-demand-from-submodule-recurse-config &&
140 git commit -m "Recurse submodule.recurse from config junk"
141 ) &&
143 cd work &&
144 git add gar/bage &&
145 git commit -m "Recurse submodule.recurse from config for gar/bage" &&
146 git -c submodule.recurse push ../pub.git main &&
147 # Check that the supermodule commit got there
148 git fetch ../pub.git &&
149 git diff --quiet FETCH_HEAD main &&
150 # Check that the submodule commit got there too
151 cd gar/bage &&
152 git diff --quiet origin/main main
156 test_expect_success 'push recurse-submodules on command line overrides config' '
158 cd work/gar/bage &&
159 >recurse-check-on-command-line-overriding-config &&
160 git add recurse-check-on-command-line-overriding-config &&
161 git commit -m "Recurse on command-line overriding config junk"
162 ) &&
164 cd work &&
165 git add gar/bage &&
166 git commit -m "Recurse on command-line overriding config for gar/bage" &&
168 # Ensure that we can override on-demand in the config
169 # to just check submodules
170 test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git main &&
171 # Check that the supermodule commit did not get there
172 git fetch ../pub.git &&
173 git diff --quiet FETCH_HEAD main^ &&
174 # Check that the submodule commit did not get there
175 (cd gar/bage && git diff --quiet origin/main main^) &&
177 # Ensure that we can override check in the config to
178 # disable submodule recursion entirely
179 (cd gar/bage && git diff --quiet origin/main main^) &&
180 git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git main &&
181 git fetch ../pub.git &&
182 git diff --quiet FETCH_HEAD main &&
183 (cd gar/bage && git diff --quiet origin/main main^) &&
185 # Ensure that we can override check in the config to
186 # disable submodule recursion entirely (alternative form)
187 git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git main &&
188 git fetch ../pub.git &&
189 git diff --quiet FETCH_HEAD main &&
190 (cd gar/bage && git diff --quiet origin/main main^) &&
192 # Ensure that we can override check in the config to
193 # push the submodule too
194 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
195 git fetch ../pub.git &&
196 git diff --quiet FETCH_HEAD main &&
197 (cd gar/bage && git diff --quiet origin/main main)
201 test_expect_success 'push recurse-submodules last one wins on command line' '
203 cd work/gar/bage &&
204 >recurse-check-on-command-line-overriding-earlier-command-line &&
205 git add recurse-check-on-command-line-overriding-earlier-command-line &&
206 git commit -m "Recurse on command-line overridiing earlier command-line junk"
207 ) &&
209 cd work &&
210 git add gar/bage &&
211 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
213 # should result in "check"
214 test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git main &&
215 # Check that the supermodule commit did not get there
216 git fetch ../pub.git &&
217 git diff --quiet FETCH_HEAD main^ &&
218 # Check that the submodule commit did not get there
219 (cd gar/bage && git diff --quiet origin/main main^) &&
221 # should result in "no"
222 git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git main &&
223 # Check that the supermodule commit did get there
224 git fetch ../pub.git &&
225 git diff --quiet FETCH_HEAD main &&
226 # Check that the submodule commit did not get there
227 (cd gar/bage && git diff --quiet origin/main main^) &&
229 # should result in "no"
230 git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git main &&
231 # Check that the submodule commit did not get there
232 (cd gar/bage && git diff --quiet origin/main main^) &&
234 # But the options in the other order should push the submodule
235 git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git main &&
236 # Check that the submodule commit did get there
237 git fetch ../pub.git &&
238 (cd gar/bage && git diff --quiet origin/main main)
242 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
244 cd work/gar/bage &&
245 >recurse-on-demand-on-command-line-overriding-config &&
246 git add recurse-on-demand-on-command-line-overriding-config &&
247 git commit -m "Recurse on-demand on command-line overriding config junk"
248 ) &&
250 cd work &&
251 git add gar/bage &&
252 git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
253 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
254 # Check that the supermodule commit got there
255 git fetch ../pub.git &&
256 git diff --quiet FETCH_HEAD main &&
257 # Check that the submodule commit got there
258 cd gar/bage &&
259 git diff --quiet origin/main main
263 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
265 cd work/gar/bage &&
266 >recurse-disable-on-command-line-overriding-config &&
267 git add recurse-disable-on-command-line-overriding-config &&
268 git commit -m "Recurse disable on command-line overriding config junk"
269 ) &&
271 cd work &&
272 git add gar/bage &&
273 git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
274 git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git main &&
275 # Check that the supermodule commit got there
276 git fetch ../pub.git &&
277 git diff --quiet FETCH_HEAD main &&
278 # But that the submodule commit did not
279 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
280 # Now push it to avoid confusing future tests
281 git push --recurse-submodules=on-demand ../pub.git main
285 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
287 cd work/gar/bage &&
288 >recurse-disable-on-command-line-alt-overriding-config &&
289 git add recurse-disable-on-command-line-alt-overriding-config &&
290 git commit -m "Recurse disable on command-line alternative overriding config junk"
291 ) &&
293 cd work &&
294 git add gar/bage &&
295 git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
296 git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git main &&
297 # Check that the supermodule commit got there
298 git fetch ../pub.git &&
299 git diff --quiet FETCH_HEAD main &&
300 # But that the submodule commit did not
301 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
302 # Now push it to avoid confusing future tests
303 git push --recurse-submodules=on-demand ../pub.git main
307 test_expect_success 'submodule entry pointing at a tag is error' '
308 git -C work/gar/bage tag -a test1 -m "tag" &&
309 tag=$(git -C work/gar/bage rev-parse test1^{tag}) &&
310 git -C work update-index --cacheinfo 160000 "$tag" gar/bage &&
311 git -C work commit -m "bad commit" &&
312 test_when_finished "git -C work reset --hard HEAD^" &&
313 test_must_fail git -C work push --recurse-submodules=on-demand ../pub.git main 2>err &&
314 test_grep "is a tag, not a commit" err
317 test_expect_success 'push fails if recurse submodules option passed as yes' '
319 cd work/gar/bage &&
320 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
321 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
322 git commit -m "Recurse push fails if recurse submodules option passed as yes"
323 ) &&
325 cd work &&
326 git add gar/bage &&
327 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
328 test_must_fail git push --recurse-submodules=yes ../pub.git main &&
329 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git main &&
330 git push --recurse-submodules=on-demand ../pub.git main
334 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
336 cd work/gar/bage &&
337 >junk4 &&
338 git add junk4 &&
339 git commit -m "Fourth junk"
340 ) &&
342 cd work &&
343 git branch branch2 &&
344 git add gar/bage &&
345 git commit -m "Fourth commit for gar/bage" &&
346 git checkout branch2 &&
348 cd gar/bage &&
349 git checkout HEAD~1
350 ) &&
351 >junk1 &&
352 git add junk1 &&
353 git commit -m "First junk" &&
354 test_must_fail git push --recurse-submodules=check ../pub.git
358 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
359 git init --bare a &&
360 git clone a a1 &&
362 cd a1 &&
363 git init b &&
365 cd b &&
366 >junk &&
367 git add junk &&
368 git commit -m "initial"
369 ) &&
370 git add b &&
371 git commit -m "added submodule" &&
372 git push --recurse-submodules=check origin main
376 test_expect_success 'push unpushed submodules when not needed' '
378 cd work &&
380 cd gar/bage &&
381 git checkout main &&
382 >junk5 &&
383 git add junk5 &&
384 git commit -m "Fifth junk" &&
385 git push &&
386 git rev-parse origin/main >../../../expected
387 ) &&
388 git checkout main &&
389 git add gar/bage &&
390 git commit -m "Fifth commit for gar/bage" &&
391 git push --recurse-submodules=on-demand ../pub.git main
392 ) &&
394 cd submodule.git &&
395 git rev-parse main >../actual
396 ) &&
397 test_cmp expected actual
400 test_expect_success 'push unpushed submodules when not needed 2' '
402 cd submodule.git &&
403 git rev-parse main >../expected
404 ) &&
406 cd work &&
408 cd gar/bage &&
409 >junk6 &&
410 git add junk6 &&
411 git commit -m "Sixth junk"
412 ) &&
413 >junk2 &&
414 git add junk2 &&
415 git commit -m "Second junk for work" &&
416 git push --recurse-submodules=on-demand ../pub.git main
417 ) &&
419 cd submodule.git &&
420 git rev-parse main >../actual
421 ) &&
422 test_cmp expected actual
425 test_expect_success 'push unpushed submodules recursively' '
427 cd work &&
429 cd gar/bage &&
430 git checkout main &&
431 > junk7 &&
432 git add junk7 &&
433 git commit -m "Seventh junk" &&
434 git rev-parse main >../../../expected
435 ) &&
436 git checkout main &&
437 git add gar/bage &&
438 git commit -m "Seventh commit for gar/bage" &&
439 git push --recurse-submodules=on-demand ../pub.git main
440 ) &&
442 cd submodule.git &&
443 git rev-parse main >../actual
444 ) &&
445 test_cmp expected actual
448 test_expect_success 'push unpushable submodule recursively fails' '
450 cd work &&
452 cd gar/bage &&
453 git rev-parse origin/main >../../../expected &&
454 git checkout main~0 &&
455 > junk8 &&
456 git add junk8 &&
457 git commit -m "Eighth junk"
458 ) &&
459 git add gar/bage &&
460 git commit -m "Eighth commit for gar/bage" &&
461 test_must_fail git push --recurse-submodules=on-demand ../pub.git main
462 ) &&
464 cd submodule.git &&
465 git rev-parse main >../actual
466 ) &&
467 test_when_finished git -C work reset --hard main^ &&
468 test_cmp expected actual
471 test_expect_success 'push --dry-run does not recursively update submodules' '
473 cd work/gar/bage &&
474 git checkout main &&
475 git rev-parse main >../../../expected_submodule &&
476 > junk9 &&
477 git add junk9 &&
478 git commit -m "Ninth junk" &&
480 # Go up to 'work' directory
481 cd ../.. &&
482 git checkout main &&
483 git rev-parse main >../expected_pub &&
484 git add gar/bage &&
485 git commit -m "Ninth commit for gar/bage" &&
486 git push --dry-run --recurse-submodules=on-demand ../pub.git main
487 ) &&
488 git -C submodule.git rev-parse main >actual_submodule &&
489 git -C pub.git rev-parse main >actual_pub &&
490 test_cmp expected_pub actual_pub &&
491 test_cmp expected_submodule actual_submodule
494 test_expect_success 'push --dry-run does not recursively update submodules' '
495 git -C work push --dry-run --recurse-submodules=only ../pub.git main &&
497 git -C submodule.git rev-parse main >actual_submodule &&
498 git -C pub.git rev-parse main >actual_pub &&
499 test_cmp expected_pub actual_pub &&
500 test_cmp expected_submodule actual_submodule
503 test_expect_success 'push only unpushed submodules recursively' '
504 git -C work/gar/bage rev-parse main >expected_submodule &&
505 git -C pub.git rev-parse main >expected_pub &&
507 git -C work push --recurse-submodules=only ../pub.git main &&
509 git -C submodule.git rev-parse main >actual_submodule &&
510 git -C pub.git rev-parse main >actual_pub &&
511 test_cmp expected_submodule actual_submodule &&
512 test_cmp expected_pub actual_pub
515 setup_subsub () {
516 git init upstream &&
517 git init upstream/sub &&
518 git init upstream/sub/deepsub &&
519 test_commit -C upstream/sub/deepsub innermost &&
520 git -C upstream/sub submodule add ./deepsub deepsub &&
521 git -C upstream/sub commit -m middle &&
522 git -C upstream submodule add ./sub sub &&
523 git -C upstream commit -m outermost &&
525 git -c protocol.file.allow=always clone --recurse-submodules upstream downstream &&
526 git -C downstream/sub/deepsub checkout -b downstream-branch &&
527 git -C downstream/sub checkout -b downstream-branch &&
528 git -C downstream checkout -b downstream-branch
531 new_downstream_commits () {
532 test_commit -C downstream/sub/deepsub new-innermost &&
533 git -C downstream/sub add deepsub &&
534 git -C downstream/sub commit -m new-middle &&
535 git -C downstream add sub &&
536 git -C downstream commit -m new-outermost
539 test_expect_success 'push with push.recurseSubmodules=only on superproject' '
540 test_when_finished rm -rf upstream downstream &&
541 setup_subsub &&
542 new_downstream_commits &&
543 git -C downstream config push.recurseSubmodules only &&
544 git -C downstream push origin downstream-branch &&
546 test_must_fail git -C upstream rev-parse refs/heads/downstream-branch &&
547 git -C upstream/sub rev-parse refs/heads/downstream-branch &&
548 test_must_fail git -C upstream/sub/deepsub rev-parse refs/heads/downstream-branch
551 test_expect_success 'push with push.recurseSubmodules=only on superproject and top-level submodule' '
552 test_when_finished rm -rf upstream downstream &&
553 setup_subsub &&
554 new_downstream_commits &&
555 git -C downstream config push.recurseSubmodules only &&
556 git -C downstream/sub config push.recurseSubmodules only &&
557 git -C downstream push origin downstream-branch 2> err &&
559 test_must_fail git -C upstream rev-parse refs/heads/downstream-branch &&
560 git -C upstream/sub rev-parse refs/heads/downstream-branch &&
561 git -C upstream/sub/deepsub rev-parse refs/heads/downstream-branch &&
562 grep "recursing into submodule with push.recurseSubmodules=only; using on-demand instead" err
565 test_expect_success 'push propagating the remotes name to a submodule' '
566 git -C work remote add origin ../pub.git &&
567 git -C work remote add pub ../pub.git &&
569 > work/gar/bage/junk10 &&
570 git -C work/gar/bage add junk10 &&
571 git -C work/gar/bage commit -m "Tenth junk" &&
572 git -C work add gar/bage &&
573 git -C work commit -m "Tenth junk added to gar/bage" &&
575 # Fails when submodule does not have a matching remote
576 test_must_fail git -C work push --recurse-submodules=on-demand pub main &&
577 # Succeeds when submodules has matching remote and refspec
578 git -C work push --recurse-submodules=on-demand origin main &&
580 git -C submodule.git rev-parse main >actual_submodule &&
581 git -C pub.git rev-parse main >actual_pub &&
582 git -C work/gar/bage rev-parse main >expected_submodule &&
583 git -C work rev-parse main >expected_pub &&
584 test_cmp expected_submodule actual_submodule &&
585 test_cmp expected_pub actual_pub
588 test_expect_success 'push propagating refspec to a submodule' '
589 > work/gar/bage/junk11 &&
590 git -C work/gar/bage add junk11 &&
591 git -C work/gar/bage commit -m "Eleventh junk" &&
593 git -C work checkout branch2 &&
594 git -C work add gar/bage &&
595 git -C work commit -m "updating gar/bage in branch2" &&
597 # Fails when submodule does not have a matching branch
598 test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
599 # Fails when refspec includes an object id
600 test_must_fail git -C work push --recurse-submodules=on-demand origin \
601 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
602 # Fails when refspec includes HEAD and parent and submodule do not
603 # have the same named branch checked out
604 test_must_fail git -C work push --recurse-submodules=on-demand origin \
605 HEAD:refs/heads/branch2 &&
607 git -C work/gar/bage branch branch2 main &&
608 git -C work push --recurse-submodules=on-demand origin branch2 &&
610 git -C submodule.git rev-parse branch2 >actual_submodule &&
611 git -C pub.git rev-parse branch2 >actual_pub &&
612 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
613 git -C work rev-parse branch2 >expected_pub &&
614 test_cmp expected_submodule actual_submodule &&
615 test_cmp expected_pub actual_pub
618 test_expect_success 'push propagating HEAD refspec to a submodule' '
619 git -C work/gar/bage checkout branch2 &&
620 > work/gar/bage/junk12 &&
621 git -C work/gar/bage add junk12 &&
622 git -C work/gar/bage commit -m "Twelfth junk" &&
624 git -C work checkout branch2 &&
625 git -C work add gar/bage &&
626 git -C work commit -m "updating gar/bage in branch2" &&
628 # Passes since the superproject and submodules HEAD are both on branch2
629 git -C work push --recurse-submodules=on-demand origin \
630 HEAD:refs/heads/branch2 &&
632 git -C submodule.git rev-parse branch2 >actual_submodule &&
633 git -C pub.git rev-parse branch2 >actual_pub &&
634 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
635 git -C work rev-parse branch2 >expected_pub &&
636 test_cmp expected_submodule actual_submodule &&
637 test_cmp expected_pub actual_pub
640 test_done