3 test_description='test push with submodules'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 test_expect_success setup '
12 GIT_DIR=pub.git git init --bare &&
13 GIT_DIR=pub.git git config receive.fsckobjects true &&
18 git config push.default matching &&
23 git config push.default matching &&
26 git commit -m "Initial junk"
29 git commit -m "Initial superproject"
33 test_expect_success 'push works with recorded gitlink' '
36 git push ../pub.git main
40 test_expect_success 'push if submodule has no remote' '
45 git commit -m "Second junk"
50 git commit -m "Second commit for gar/bage" &&
51 git push --recurse-submodules=check ../pub.git main
55 test_expect_success 'push fails if submodule commit not on remote' '
58 git clone --bare bage ../../submodule.git &&
60 git remote add origin ../../../submodule.git &&
64 git commit -m "Third junk"
69 git commit -m "Third commit for gar/bage" &&
70 # the push should fail with --recurse-submodules=check
71 # on the command line...
72 test_must_fail git push --recurse-submodules=check ../pub.git main &&
74 # ...or if specified in the configuration..
75 test_must_fail git -c push.recurseSubmodules=check push ../pub.git main
79 test_expect_success 'push succeeds after commit was pushed to remote' '
86 git push --recurse-submodules=check ../pub.git main
90 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
93 >recurse-on-demand-on-command-line &&
94 git add recurse-on-demand-on-command-line &&
95 git commit -m "Recurse on-demand on command line junk"
100 git commit -m "Recurse on-demand on command line for gar/bage" &&
101 git push --recurse-submodules=on-demand ../pub.git main &&
102 # Check that the supermodule commit got there
103 git fetch ../pub.git &&
104 git diff --quiet FETCH_HEAD main &&
105 # Check that the submodule commit got there too
107 git diff --quiet origin/main main
111 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
114 >recurse-on-demand-from-config &&
115 git add recurse-on-demand-from-config &&
116 git commit -m "Recurse on-demand from config junk"
121 git commit -m "Recurse on-demand from config for gar/bage" &&
122 git -c push.recurseSubmodules=on-demand push ../pub.git main &&
123 # Check that the supermodule commit got there
124 git fetch ../pub.git &&
125 git diff --quiet FETCH_HEAD main &&
126 # Check that the submodule commit got there too
128 git diff --quiet origin/main main
132 test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
135 >recurse-on-demand-from-submodule-recurse-config &&
136 git add recurse-on-demand-from-submodule-recurse-config &&
137 git commit -m "Recurse submodule.recurse from config junk"
142 git commit -m "Recurse submodule.recurse from config for gar/bage" &&
143 git -c submodule.recurse push ../pub.git main &&
144 # Check that the supermodule commit got there
145 git fetch ../pub.git &&
146 git diff --quiet FETCH_HEAD main &&
147 # Check that the submodule commit got there too
149 git diff --quiet origin/main main
153 test_expect_success 'push recurse-submodules on command line overrides config' '
156 >recurse-check-on-command-line-overriding-config &&
157 git add recurse-check-on-command-line-overriding-config &&
158 git commit -m "Recurse on command-line overriding config junk"
163 git commit -m "Recurse on command-line overriding config for gar/bage" &&
165 # Ensure that we can override on-demand in the config
166 # to just check submodules
167 test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git main &&
168 # Check that the supermodule commit did not get there
169 git fetch ../pub.git &&
170 git diff --quiet FETCH_HEAD main^ &&
171 # Check that the submodule commit did not get there
172 (cd gar/bage && git diff --quiet origin/main main^) &&
174 # Ensure that we can override check in the config to
175 # disable submodule recursion entirely
176 (cd gar/bage && git diff --quiet origin/main main^) &&
177 git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git main &&
178 git fetch ../pub.git &&
179 git diff --quiet FETCH_HEAD main &&
180 (cd gar/bage && git diff --quiet origin/main main^) &&
182 # Ensure that we can override check in the config to
183 # disable submodule recursion entirely (alternative form)
184 git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git main &&
185 git fetch ../pub.git &&
186 git diff --quiet FETCH_HEAD main &&
187 (cd gar/bage && git diff --quiet origin/main main^) &&
189 # Ensure that we can override check in the config to
190 # push the submodule too
191 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
192 git fetch ../pub.git &&
193 git diff --quiet FETCH_HEAD main &&
194 (cd gar/bage && git diff --quiet origin/main main)
198 test_expect_success 'push recurse-submodules last one wins on command line' '
201 >recurse-check-on-command-line-overriding-earlier-command-line &&
202 git add recurse-check-on-command-line-overriding-earlier-command-line &&
203 git commit -m "Recurse on command-line overridiing earlier command-line junk"
208 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
210 # should result in "check"
211 test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git main &&
212 # Check that the supermodule commit did not get there
213 git fetch ../pub.git &&
214 git diff --quiet FETCH_HEAD main^ &&
215 # Check that the submodule commit did not get there
216 (cd gar/bage && git diff --quiet origin/main main^) &&
218 # should result in "no"
219 git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git main &&
220 # Check that the supermodule commit did get there
221 git fetch ../pub.git &&
222 git diff --quiet FETCH_HEAD main &&
223 # Check that the submodule commit did not get there
224 (cd gar/bage && git diff --quiet origin/main main^) &&
226 # should result in "no"
227 git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git main &&
228 # Check that the submodule commit did not get there
229 (cd gar/bage && git diff --quiet origin/main main^) &&
231 # But the options in the other order should push the submodule
232 git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git main &&
233 # Check that the submodule commit did get there
234 git fetch ../pub.git &&
235 (cd gar/bage && git diff --quiet origin/main main)
239 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
242 >recurse-on-demand-on-command-line-overriding-config &&
243 git add recurse-on-demand-on-command-line-overriding-config &&
244 git commit -m "Recurse on-demand on command-line overriding config junk"
249 git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
250 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
251 # Check that the supermodule commit got there
252 git fetch ../pub.git &&
253 git diff --quiet FETCH_HEAD main &&
254 # Check that the submodule commit got there
256 git diff --quiet origin/main main
260 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
263 >recurse-disable-on-command-line-overriding-config &&
264 git add recurse-disable-on-command-line-overriding-config &&
265 git commit -m "Recurse disable on command-line overriding config junk"
270 git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
271 git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git main &&
272 # Check that the supermodule commit got there
273 git fetch ../pub.git &&
274 git diff --quiet FETCH_HEAD main &&
275 # But that the submodule commit did not
276 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
277 # Now push it to avoid confusing future tests
278 git push --recurse-submodules=on-demand ../pub.git main
282 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
285 >recurse-disable-on-command-line-alt-overriding-config &&
286 git add recurse-disable-on-command-line-alt-overriding-config &&
287 git commit -m "Recurse disable on command-line alternative overriding config junk"
292 git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
293 git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git main &&
294 # Check that the supermodule commit got there
295 git fetch ../pub.git &&
296 git diff --quiet FETCH_HEAD main &&
297 # But that the submodule commit did not
298 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
299 # Now push it to avoid confusing future tests
300 git push --recurse-submodules=on-demand ../pub.git main
304 test_expect_success 'submodule entry pointing at a tag is error' '
305 git -C work/gar/bage tag -a test1 -m "tag" &&
306 tag=$(git -C work/gar/bage rev-parse test1^{tag}) &&
307 git -C work update-index --cacheinfo 160000 "$tag" gar/bage &&
308 git -C work commit -m "bad commit" &&
309 test_when_finished "git -C work reset --hard HEAD^" &&
310 test_must_fail git -C work push --recurse-submodules=on-demand ../pub.git main 2>err &&
311 test_i18ngrep "is a tag, not a commit" err
314 test_expect_success 'push fails if recurse submodules option passed as yes' '
317 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
318 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
319 git commit -m "Recurse push fails if recurse submodules option passed as yes"
324 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
325 test_must_fail git push --recurse-submodules=yes ../pub.git main &&
326 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git main &&
327 git push --recurse-submodules=on-demand ../pub.git main
331 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
336 git commit -m "Fourth junk"
340 git branch branch2 &&
342 git commit -m "Fourth commit for gar/bage" &&
343 git checkout branch2 &&
350 git commit -m "First junk" &&
351 test_must_fail git push --recurse-submodules=check ../pub.git
355 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
365 git commit -m "initial"
368 git commit -m "added submodule" &&
369 git push --recurse-submodules=check origin main
373 test_expect_success 'push unpushed submodules when not needed' '
381 git commit -m "Fifth junk" &&
383 git rev-parse origin/main >../../../expected
387 git commit -m "Fifth commit for gar/bage" &&
388 git push --recurse-submodules=on-demand ../pub.git main
392 git rev-parse main >../actual
394 test_cmp expected actual
397 test_expect_success 'push unpushed submodules when not needed 2' '
400 git rev-parse main >../expected
408 git commit -m "Sixth junk"
412 git commit -m "Second junk for work" &&
413 git push --recurse-submodules=on-demand ../pub.git main
417 git rev-parse main >../actual
419 test_cmp expected actual
422 test_expect_success 'push unpushed submodules recursively' '
430 git commit -m "Seventh junk" &&
431 git rev-parse main >../../../expected
435 git commit -m "Seventh commit for gar/bage" &&
436 git push --recurse-submodules=on-demand ../pub.git main
440 git rev-parse main >../actual
442 test_cmp expected actual
445 test_expect_success 'push unpushable submodule recursively fails' '
450 git rev-parse origin/main >../../../expected &&
451 git checkout main~0 &&
454 git commit -m "Eighth junk"
457 git commit -m "Eighth commit for gar/bage" &&
458 test_must_fail git push --recurse-submodules=on-demand ../pub.git main
462 git rev-parse main >../actual
464 test_when_finished git -C work reset --hard main^ &&
465 test_cmp expected actual
468 test_expect_success 'push --dry-run does not recursively update submodules' '
472 git rev-parse main >../../../expected_submodule &&
475 git commit -m "Ninth junk" &&
477 # Go up to 'work' directory
480 git rev-parse main >../expected_pub &&
482 git commit -m "Ninth commit for gar/bage" &&
483 git push --dry-run --recurse-submodules=on-demand ../pub.git main
485 git -C submodule.git rev-parse main >actual_submodule &&
486 git -C pub.git rev-parse main >actual_pub &&
487 test_cmp expected_pub actual_pub &&
488 test_cmp expected_submodule actual_submodule
491 test_expect_success 'push --dry-run does not recursively update submodules' '
492 git -C work push --dry-run --recurse-submodules=only ../pub.git main &&
494 git -C submodule.git rev-parse main >actual_submodule &&
495 git -C pub.git rev-parse main >actual_pub &&
496 test_cmp expected_pub actual_pub &&
497 test_cmp expected_submodule actual_submodule
500 test_expect_success 'push only unpushed submodules recursively' '
501 git -C work/gar/bage rev-parse main >expected_submodule &&
502 git -C pub.git rev-parse main >expected_pub &&
504 git -C work push --recurse-submodules=only ../pub.git main &&
506 git -C submodule.git rev-parse main >actual_submodule &&
507 git -C pub.git rev-parse main >actual_pub &&
508 test_cmp expected_submodule actual_submodule &&
509 test_cmp expected_pub actual_pub
512 test_expect_success 'push propagating the remotes name to a submodule' '
513 git -C work remote add origin ../pub.git &&
514 git -C work remote add pub ../pub.git &&
516 > work/gar/bage/junk10 &&
517 git -C work/gar/bage add junk10 &&
518 git -C work/gar/bage commit -m "Tenth junk" &&
519 git -C work add gar/bage &&
520 git -C work commit -m "Tenth junk added to gar/bage" &&
522 # Fails when submodule does not have a matching remote
523 test_must_fail git -C work push --recurse-submodules=on-demand pub main &&
524 # Succeeds when submodules has matching remote and refspec
525 git -C work push --recurse-submodules=on-demand origin main &&
527 git -C submodule.git rev-parse main >actual_submodule &&
528 git -C pub.git rev-parse main >actual_pub &&
529 git -C work/gar/bage rev-parse main >expected_submodule &&
530 git -C work rev-parse main >expected_pub &&
531 test_cmp expected_submodule actual_submodule &&
532 test_cmp expected_pub actual_pub
535 test_expect_success 'push propagating refspec to a submodule' '
536 > work/gar/bage/junk11 &&
537 git -C work/gar/bage add junk11 &&
538 git -C work/gar/bage commit -m "Eleventh junk" &&
540 git -C work checkout branch2 &&
541 git -C work add gar/bage &&
542 git -C work commit -m "updating gar/bage in branch2" &&
544 # Fails when submodule does not have a matching branch
545 test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
546 # Fails when refspec includes an object id
547 test_must_fail git -C work push --recurse-submodules=on-demand origin \
548 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
549 # Fails when refspec includes HEAD and parent and submodule do not
550 # have the same named branch checked out
551 test_must_fail git -C work push --recurse-submodules=on-demand origin \
552 HEAD:refs/heads/branch2 &&
554 git -C work/gar/bage branch branch2 main &&
555 git -C work push --recurse-submodules=on-demand origin branch2 &&
557 git -C submodule.git rev-parse branch2 >actual_submodule &&
558 git -C pub.git rev-parse branch2 >actual_pub &&
559 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
560 git -C work rev-parse branch2 >expected_pub &&
561 test_cmp expected_submodule actual_submodule &&
562 test_cmp expected_pub actual_pub
565 test_expect_success 'push propagating HEAD refspec to a submodule' '
566 git -C work/gar/bage checkout branch2 &&
567 > work/gar/bage/junk12 &&
568 git -C work/gar/bage add junk12 &&
569 git -C work/gar/bage commit -m "Twelfth junk" &&
571 git -C work checkout branch2 &&
572 git -C work add gar/bage &&
573 git -C work commit -m "updating gar/bage in branch2" &&
575 # Passes since the superproject and submodules HEAD are both on branch2
576 git -C work push --recurse-submodules=on-demand origin \
577 HEAD:refs/heads/branch2 &&
579 git -C submodule.git rev-parse branch2 >actual_submodule &&
580 git -C pub.git rev-parse branch2 >actual_pub &&
581 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
582 git -C work rev-parse branch2 >expected_pub &&
583 test_cmp expected_submodule actual_submodule &&
584 test_cmp expected_pub actual_pub