Merge branch 'es/worktree-repair-copied' into cw/worktrees-relative
[git/gitster.git] / t / t5531-deep-submodule-push.sh
blob135823630a37c69bd17e0bc7ed8c1e94233dd653
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_PASSES_SANITIZE_LEAK=true
12 . ./test-lib.sh
14 test_expect_success setup '
15 mkdir pub.git &&
16 GIT_DIR=pub.git git init --bare &&
17 GIT_DIR=pub.git git config receive.fsckobjects true &&
18 mkdir work &&
20 cd work &&
21 git init &&
22 git config push.default matching &&
23 mkdir -p gar/bage &&
25 cd gar/bage &&
26 git init &&
27 git config push.default matching &&
28 >junk &&
29 git add junk &&
30 git commit -m "Initial junk"
31 ) &&
32 git add gar/bage &&
33 git commit -m "Initial superproject"
37 test_expect_success 'push works with recorded gitlink' '
39 cd work &&
40 git push ../pub.git main
44 test_expect_success 'push if submodule has no remote' '
46 cd work/gar/bage &&
47 >junk2 &&
48 git add junk2 &&
49 git commit -m "Second junk"
50 ) &&
52 cd work &&
53 git add gar/bage &&
54 git commit -m "Second commit for gar/bage" &&
55 git push --recurse-submodules=check ../pub.git main
59 test_expect_success 'push fails if submodule commit not on remote' '
61 cd work/gar &&
62 git clone --bare bage ../../submodule.git &&
63 cd bage &&
64 git remote add origin ../../../submodule.git &&
65 git fetch &&
66 >junk3 &&
67 git add junk3 &&
68 git commit -m "Third junk"
69 ) &&
71 cd work &&
72 git add gar/bage &&
73 git commit -m "Third commit for gar/bage" &&
74 # the push should fail with --recurse-submodules=check
75 # on the command line...
76 test_must_fail git push --recurse-submodules=check ../pub.git main &&
78 # ...or if specified in the configuration..
79 test_must_fail git -c push.recurseSubmodules=check push ../pub.git main
83 test_expect_success 'push succeeds after commit was pushed to remote' '
85 cd work/gar/bage &&
86 git push origin main
87 ) &&
89 cd work &&
90 git push --recurse-submodules=check ../pub.git main
94 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
96 cd work/gar/bage &&
97 >recurse-on-demand-on-command-line &&
98 git add recurse-on-demand-on-command-line &&
99 git commit -m "Recurse on-demand on command line junk"
100 ) &&
102 cd work &&
103 git add gar/bage &&
104 git commit -m "Recurse on-demand on command line for gar/bage" &&
105 git push --recurse-submodules=on-demand ../pub.git main &&
106 # Check that the supermodule commit got there
107 git fetch ../pub.git &&
108 git diff --quiet FETCH_HEAD main &&
109 # Check that the submodule commit got there too
110 cd gar/bage &&
111 git diff --quiet origin/main main
115 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
117 cd work/gar/bage &&
118 >recurse-on-demand-from-config &&
119 git add recurse-on-demand-from-config &&
120 git commit -m "Recurse on-demand from config junk"
121 ) &&
123 cd work &&
124 git add gar/bage &&
125 git commit -m "Recurse on-demand from config for gar/bage" &&
126 git -c push.recurseSubmodules=on-demand push ../pub.git main &&
127 # Check that the supermodule commit got there
128 git fetch ../pub.git &&
129 git diff --quiet FETCH_HEAD main &&
130 # Check that the submodule commit got there too
131 cd gar/bage &&
132 git diff --quiet origin/main main
136 test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
138 cd work/gar/bage &&
139 >recurse-on-demand-from-submodule-recurse-config &&
140 git add recurse-on-demand-from-submodule-recurse-config &&
141 git commit -m "Recurse submodule.recurse from config junk"
142 ) &&
144 cd work &&
145 git add gar/bage &&
146 git commit -m "Recurse submodule.recurse from config for gar/bage" &&
147 git -c submodule.recurse push ../pub.git main &&
148 # Check that the supermodule commit got there
149 git fetch ../pub.git &&
150 git diff --quiet FETCH_HEAD main &&
151 # Check that the submodule commit got there too
152 cd gar/bage &&
153 git diff --quiet origin/main main
157 test_expect_success 'push recurse-submodules on command line overrides config' '
159 cd work/gar/bage &&
160 >recurse-check-on-command-line-overriding-config &&
161 git add recurse-check-on-command-line-overriding-config &&
162 git commit -m "Recurse on command-line overriding config junk"
163 ) &&
165 cd work &&
166 git add gar/bage &&
167 git commit -m "Recurse on command-line overriding config for gar/bage" &&
169 # Ensure that we can override on-demand in the config
170 # to just check submodules
171 test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git main &&
172 # Check that the supermodule commit did not get there
173 git fetch ../pub.git &&
174 git diff --quiet FETCH_HEAD main^ &&
175 # Check that the submodule commit did not get there
176 (cd gar/bage && git diff --quiet origin/main main^) &&
178 # Ensure that we can override check in the config to
179 # disable submodule recursion entirely
180 (cd gar/bage && git diff --quiet origin/main main^) &&
181 git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git main &&
182 git fetch ../pub.git &&
183 git diff --quiet FETCH_HEAD main &&
184 (cd gar/bage && git diff --quiet origin/main main^) &&
186 # Ensure that we can override check in the config to
187 # disable submodule recursion entirely (alternative form)
188 git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git main &&
189 git fetch ../pub.git &&
190 git diff --quiet FETCH_HEAD main &&
191 (cd gar/bage && git diff --quiet origin/main main^) &&
193 # Ensure that we can override check in the config to
194 # push the submodule too
195 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
196 git fetch ../pub.git &&
197 git diff --quiet FETCH_HEAD main &&
198 (cd gar/bage && git diff --quiet origin/main main)
202 test_expect_success 'push recurse-submodules last one wins on command line' '
204 cd work/gar/bage &&
205 >recurse-check-on-command-line-overriding-earlier-command-line &&
206 git add recurse-check-on-command-line-overriding-earlier-command-line &&
207 git commit -m "Recurse on command-line overridiing earlier command-line junk"
208 ) &&
210 cd work &&
211 git add gar/bage &&
212 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
214 # should result in "check"
215 test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git main &&
216 # Check that the supermodule commit did not get there
217 git fetch ../pub.git &&
218 git diff --quiet FETCH_HEAD main^ &&
219 # Check that the submodule commit did not get there
220 (cd gar/bage && git diff --quiet origin/main main^) &&
222 # should result in "no"
223 git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git main &&
224 # Check that the supermodule commit did get there
225 git fetch ../pub.git &&
226 git diff --quiet FETCH_HEAD main &&
227 # Check that the submodule commit did not get there
228 (cd gar/bage && git diff --quiet origin/main main^) &&
230 # should result in "no"
231 git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git main &&
232 # Check that the submodule commit did not get there
233 (cd gar/bage && git diff --quiet origin/main main^) &&
235 # But the options in the other order should push the submodule
236 git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git main &&
237 # Check that the submodule commit did get there
238 git fetch ../pub.git &&
239 (cd gar/bage && git diff --quiet origin/main main)
243 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
245 cd work/gar/bage &&
246 >recurse-on-demand-on-command-line-overriding-config &&
247 git add recurse-on-demand-on-command-line-overriding-config &&
248 git commit -m "Recurse on-demand on command-line overriding config junk"
249 ) &&
251 cd work &&
252 git add gar/bage &&
253 git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
254 git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git main &&
255 # Check that the supermodule commit got there
256 git fetch ../pub.git &&
257 git diff --quiet FETCH_HEAD main &&
258 # Check that the submodule commit got there
259 cd gar/bage &&
260 git diff --quiet origin/main main
264 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
266 cd work/gar/bage &&
267 >recurse-disable-on-command-line-overriding-config &&
268 git add recurse-disable-on-command-line-overriding-config &&
269 git commit -m "Recurse disable on command-line overriding config junk"
270 ) &&
272 cd work &&
273 git add gar/bage &&
274 git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
275 git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git main &&
276 # Check that the supermodule commit got there
277 git fetch ../pub.git &&
278 git diff --quiet FETCH_HEAD main &&
279 # But that the submodule commit did not
280 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
281 # Now push it to avoid confusing future tests
282 git push --recurse-submodules=on-demand ../pub.git main
286 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
288 cd work/gar/bage &&
289 >recurse-disable-on-command-line-alt-overriding-config &&
290 git add recurse-disable-on-command-line-alt-overriding-config &&
291 git commit -m "Recurse disable on command-line alternative overriding config junk"
292 ) &&
294 cd work &&
295 git add gar/bage &&
296 git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
297 git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git main &&
298 # Check that the supermodule commit got there
299 git fetch ../pub.git &&
300 git diff --quiet FETCH_HEAD main &&
301 # But that the submodule commit did not
302 ( cd gar/bage && git diff --quiet origin/main main^ ) &&
303 # Now push it to avoid confusing future tests
304 git push --recurse-submodules=on-demand ../pub.git main
308 test_expect_success 'submodule entry pointing at a tag is error' '
309 git -C work/gar/bage tag -a test1 -m "tag" &&
310 tag=$(git -C work/gar/bage rev-parse test1^{tag}) &&
311 git -C work update-index --cacheinfo 160000 "$tag" gar/bage &&
312 git -C work commit -m "bad commit" &&
313 test_when_finished "git -C work reset --hard HEAD^" &&
314 test_must_fail git -C work push --recurse-submodules=on-demand ../pub.git main 2>err &&
315 test_grep "is a tag, not a commit" err
318 test_expect_success 'push fails if recurse submodules option passed as yes' '
320 cd work/gar/bage &&
321 >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
322 git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
323 git commit -m "Recurse push fails if recurse submodules option passed as yes"
324 ) &&
326 cd work &&
327 git add gar/bage &&
328 git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
329 test_must_fail git push --recurse-submodules=yes ../pub.git main &&
330 test_must_fail git -c push.recurseSubmodules=yes push ../pub.git main &&
331 git push --recurse-submodules=on-demand ../pub.git main
335 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
337 cd work/gar/bage &&
338 >junk4 &&
339 git add junk4 &&
340 git commit -m "Fourth junk"
341 ) &&
343 cd work &&
344 git branch branch2 &&
345 git add gar/bage &&
346 git commit -m "Fourth commit for gar/bage" &&
347 git checkout branch2 &&
349 cd gar/bage &&
350 git checkout HEAD~1
351 ) &&
352 >junk1 &&
353 git add junk1 &&
354 git commit -m "First junk" &&
355 test_must_fail git push --recurse-submodules=check ../pub.git
359 test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
360 git init --bare a &&
361 git clone a a1 &&
363 cd a1 &&
364 git init b &&
366 cd b &&
367 >junk &&
368 git add junk &&
369 git commit -m "initial"
370 ) &&
371 git add b &&
372 git commit -m "added submodule" &&
373 git push --recurse-submodules=check origin main
377 test_expect_success 'push unpushed submodules when not needed' '
379 cd work &&
381 cd gar/bage &&
382 git checkout main &&
383 >junk5 &&
384 git add junk5 &&
385 git commit -m "Fifth junk" &&
386 git push &&
387 git rev-parse origin/main >../../../expected
388 ) &&
389 git checkout main &&
390 git add gar/bage &&
391 git commit -m "Fifth commit for gar/bage" &&
392 git push --recurse-submodules=on-demand ../pub.git main
393 ) &&
395 cd submodule.git &&
396 git rev-parse main >../actual
397 ) &&
398 test_cmp expected actual
401 test_expect_success 'push unpushed submodules when not needed 2' '
403 cd submodule.git &&
404 git rev-parse main >../expected
405 ) &&
407 cd work &&
409 cd gar/bage &&
410 >junk6 &&
411 git add junk6 &&
412 git commit -m "Sixth junk"
413 ) &&
414 >junk2 &&
415 git add junk2 &&
416 git commit -m "Second junk for work" &&
417 git push --recurse-submodules=on-demand ../pub.git main
418 ) &&
420 cd submodule.git &&
421 git rev-parse main >../actual
422 ) &&
423 test_cmp expected actual
426 test_expect_success 'push unpushed submodules recursively' '
428 cd work &&
430 cd gar/bage &&
431 git checkout main &&
432 > junk7 &&
433 git add junk7 &&
434 git commit -m "Seventh junk" &&
435 git rev-parse main >../../../expected
436 ) &&
437 git checkout main &&
438 git add gar/bage &&
439 git commit -m "Seventh commit for gar/bage" &&
440 git push --recurse-submodules=on-demand ../pub.git main
441 ) &&
443 cd submodule.git &&
444 git rev-parse main >../actual
445 ) &&
446 test_cmp expected actual
449 test_expect_success 'push unpushable submodule recursively fails' '
451 cd work &&
453 cd gar/bage &&
454 git rev-parse origin/main >../../../expected &&
455 git checkout main~0 &&
456 > junk8 &&
457 git add junk8 &&
458 git commit -m "Eighth junk"
459 ) &&
460 git add gar/bage &&
461 git commit -m "Eighth commit for gar/bage" &&
462 test_must_fail git push --recurse-submodules=on-demand ../pub.git main
463 ) &&
465 cd submodule.git &&
466 git rev-parse main >../actual
467 ) &&
468 test_when_finished git -C work reset --hard main^ &&
469 test_cmp expected actual
472 test_expect_success 'push --dry-run does not recursively update submodules' '
474 cd work/gar/bage &&
475 git checkout main &&
476 git rev-parse main >../../../expected_submodule &&
477 > junk9 &&
478 git add junk9 &&
479 git commit -m "Ninth junk" &&
481 # Go up to 'work' directory
482 cd ../.. &&
483 git checkout main &&
484 git rev-parse main >../expected_pub &&
485 git add gar/bage &&
486 git commit -m "Ninth commit for gar/bage" &&
487 git push --dry-run --recurse-submodules=on-demand ../pub.git main
488 ) &&
489 git -C submodule.git rev-parse main >actual_submodule &&
490 git -C pub.git rev-parse main >actual_pub &&
491 test_cmp expected_pub actual_pub &&
492 test_cmp expected_submodule actual_submodule
495 test_expect_success 'push --dry-run does not recursively update submodules' '
496 git -C work push --dry-run --recurse-submodules=only ../pub.git main &&
498 git -C submodule.git rev-parse main >actual_submodule &&
499 git -C pub.git rev-parse main >actual_pub &&
500 test_cmp expected_pub actual_pub &&
501 test_cmp expected_submodule actual_submodule
504 test_expect_success 'push only unpushed submodules recursively' '
505 git -C work/gar/bage rev-parse main >expected_submodule &&
506 git -C pub.git rev-parse main >expected_pub &&
508 git -C work push --recurse-submodules=only ../pub.git main &&
510 git -C submodule.git rev-parse main >actual_submodule &&
511 git -C pub.git rev-parse main >actual_pub &&
512 test_cmp expected_submodule actual_submodule &&
513 test_cmp expected_pub actual_pub
516 setup_subsub () {
517 git init upstream &&
518 git init upstream/sub &&
519 git init upstream/sub/deepsub &&
520 test_commit -C upstream/sub/deepsub innermost &&
521 git -C upstream/sub submodule add ./deepsub deepsub &&
522 git -C upstream/sub commit -m middle &&
523 git -C upstream submodule add ./sub sub &&
524 git -C upstream commit -m outermost &&
526 git -c protocol.file.allow=always clone --recurse-submodules upstream downstream &&
527 git -C downstream/sub/deepsub checkout -b downstream-branch &&
528 git -C downstream/sub checkout -b downstream-branch &&
529 git -C downstream checkout -b downstream-branch
532 new_downstream_commits () {
533 test_commit -C downstream/sub/deepsub new-innermost &&
534 git -C downstream/sub add deepsub &&
535 git -C downstream/sub commit -m new-middle &&
536 git -C downstream add sub &&
537 git -C downstream commit -m new-outermost
540 test_expect_success 'push with push.recurseSubmodules=only on superproject' '
541 test_when_finished rm -rf upstream downstream &&
542 setup_subsub &&
543 new_downstream_commits &&
544 git -C downstream config push.recurseSubmodules only &&
545 git -C downstream push origin downstream-branch &&
547 test_must_fail git -C upstream rev-parse refs/heads/downstream-branch &&
548 git -C upstream/sub rev-parse refs/heads/downstream-branch &&
549 test_must_fail git -C upstream/sub/deepsub rev-parse refs/heads/downstream-branch
552 test_expect_success 'push with push.recurseSubmodules=only on superproject and top-level submodule' '
553 test_when_finished rm -rf upstream downstream &&
554 setup_subsub &&
555 new_downstream_commits &&
556 git -C downstream config push.recurseSubmodules only &&
557 git -C downstream/sub config push.recurseSubmodules only &&
558 git -C downstream push origin downstream-branch 2> err &&
560 test_must_fail git -C upstream rev-parse refs/heads/downstream-branch &&
561 git -C upstream/sub rev-parse refs/heads/downstream-branch &&
562 git -C upstream/sub/deepsub rev-parse refs/heads/downstream-branch &&
563 grep "recursing into submodule with push.recurseSubmodules=only; using on-demand instead" err
566 test_expect_success 'push propagating the remotes name to a submodule' '
567 git -C work remote add origin ../pub.git &&
568 git -C work remote add pub ../pub.git &&
570 > work/gar/bage/junk10 &&
571 git -C work/gar/bage add junk10 &&
572 git -C work/gar/bage commit -m "Tenth junk" &&
573 git -C work add gar/bage &&
574 git -C work commit -m "Tenth junk added to gar/bage" &&
576 # Fails when submodule does not have a matching remote
577 test_must_fail git -C work push --recurse-submodules=on-demand pub main &&
578 # Succeeds when submodules has matching remote and refspec
579 git -C work push --recurse-submodules=on-demand origin main &&
581 git -C submodule.git rev-parse main >actual_submodule &&
582 git -C pub.git rev-parse main >actual_pub &&
583 git -C work/gar/bage rev-parse main >expected_submodule &&
584 git -C work rev-parse main >expected_pub &&
585 test_cmp expected_submodule actual_submodule &&
586 test_cmp expected_pub actual_pub
589 test_expect_success 'push propagating refspec to a submodule' '
590 > work/gar/bage/junk11 &&
591 git -C work/gar/bage add junk11 &&
592 git -C work/gar/bage commit -m "Eleventh junk" &&
594 git -C work checkout branch2 &&
595 git -C work add gar/bage &&
596 git -C work commit -m "updating gar/bage in branch2" &&
598 # Fails when submodule does not have a matching branch
599 test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
600 # Fails when refspec includes an object id
601 test_must_fail git -C work push --recurse-submodules=on-demand origin \
602 "$(git -C work rev-parse branch2):refs/heads/branch2" &&
603 # Fails when refspec includes HEAD and parent and submodule do not
604 # have the same named branch checked out
605 test_must_fail git -C work push --recurse-submodules=on-demand origin \
606 HEAD:refs/heads/branch2 &&
608 git -C work/gar/bage branch branch2 main &&
609 git -C work push --recurse-submodules=on-demand origin branch2 &&
611 git -C submodule.git rev-parse branch2 >actual_submodule &&
612 git -C pub.git rev-parse branch2 >actual_pub &&
613 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
614 git -C work rev-parse branch2 >expected_pub &&
615 test_cmp expected_submodule actual_submodule &&
616 test_cmp expected_pub actual_pub
619 test_expect_success 'push propagating HEAD refspec to a submodule' '
620 git -C work/gar/bage checkout branch2 &&
621 > work/gar/bage/junk12 &&
622 git -C work/gar/bage add junk12 &&
623 git -C work/gar/bage commit -m "Twelfth junk" &&
625 git -C work checkout branch2 &&
626 git -C work add gar/bage &&
627 git -C work commit -m "updating gar/bage in branch2" &&
629 # Passes since the superproject and submodules HEAD are both on branch2
630 git -C work push --recurse-submodules=on-demand origin \
631 HEAD:refs/heads/branch2 &&
633 git -C submodule.git rev-parse branch2 >actual_submodule &&
634 git -C pub.git rev-parse branch2 >actual_pub &&
635 git -C work/gar/bage rev-parse branch2 >expected_submodule &&
636 git -C work rev-parse branch2 >expected_pub &&
637 test_cmp expected_submodule actual_submodule &&
638 test_cmp expected_pub actual_pub
641 test_done