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
13 test_expect_success setup
'
15 GIT_DIR=pub.git git init --bare &&
16 GIT_DIR=pub.git git config receive.fsckobjects true &&
21 git config push.default matching &&
26 git config push.default matching &&
29 git commit -m "Initial junk"
32 git commit -m "Initial superproject"
36 test_expect_success
'push works with recorded gitlink' '
39 git push ../pub.git main
43 test_expect_success
'push if submodule has no remote' '
48 git commit -m "Second junk"
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' '
61 git clone --bare bage ../../submodule.git &&
63 git remote add origin ../../../submodule.git &&
67 git commit -m "Third junk"
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' '
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' '
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"
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
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' '
117 >recurse-on-demand-from-config &&
118 git add recurse-on-demand-from-config &&
119 git commit -m "Recurse on-demand from config junk"
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
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' '
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"
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
152 git diff --quiet origin/main main
156 test_expect_success
'push recurse-submodules on command line overrides config' '
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"
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' '
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"
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' '
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"
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
259 git diff --quiet origin/main main
263 test_expect_success
'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
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"
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' '
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"
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_i18ngrep "is a tag, not a commit" err
317 test_expect_success
'push fails if recurse submodules option passed as yes' '
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"
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' '
339 git commit -m "Fourth junk"
343 git branch branch2 &&
345 git commit -m "Fourth commit for gar/bage" &&
346 git checkout branch2 &&
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' '
368 git commit -m "initial"
371 git commit -m "added submodule" &&
372 git push --recurse-submodules=check origin main
376 test_expect_success
'push unpushed submodules when not needed' '
384 git commit -m "Fifth junk" &&
386 git rev-parse origin/main >../../../expected
390 git commit -m "Fifth commit for gar/bage" &&
391 git push --recurse-submodules=on-demand ../pub.git main
395 git rev-parse main >../actual
397 test_cmp expected actual
400 test_expect_success
'push unpushed submodules when not needed 2' '
403 git rev-parse main >../expected
411 git commit -m "Sixth junk"
415 git commit -m "Second junk for work" &&
416 git push --recurse-submodules=on-demand ../pub.git main
420 git rev-parse main >../actual
422 test_cmp expected actual
425 test_expect_success
'push unpushed submodules recursively' '
433 git commit -m "Seventh junk" &&
434 git rev-parse main >../../../expected
438 git commit -m "Seventh commit for gar/bage" &&
439 git push --recurse-submodules=on-demand ../pub.git main
443 git rev-parse main >../actual
445 test_cmp expected actual
448 test_expect_success
'push unpushable submodule recursively fails' '
453 git rev-parse origin/main >../../../expected &&
454 git checkout main~0 &&
457 git commit -m "Eighth junk"
460 git commit -m "Eighth commit for gar/bage" &&
461 test_must_fail git push --recurse-submodules=on-demand ../pub.git main
465 git rev-parse main >../actual
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' '
475 git rev-parse main >../../../expected_submodule &&
478 git commit -m "Ninth junk" &&
480 # Go up to 'work
' directory
483 git rev-parse main >../expected_pub &&
485 git commit -m "Ninth commit for gar/bage" &&
486 git push --dry-run --recurse-submodules=on-demand ../pub.git main
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
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 &&
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 &&
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