]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5531-deep-submodule-push.sh
The third batch
[thirdparty/git.git] / t / t5531-deep-submodule-push.sh
1 #!/bin/sh
2
3 test_description='test push with submodules'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1
9 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
10
11 . ./test-lib.sh
12
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 &&
18 (
19 cd work &&
20 git init &&
21 git config push.default matching &&
22 mkdir -p gar/bage &&
23 (
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"
33 )
34 '
35
36 test_expect_success 'push works with recorded gitlink' '
37 (
38 cd work &&
39 git push ../pub.git main
40 )
41 '
42
43 test_expect_success 'push if submodule has no remote' '
44 (
45 cd work/gar/bage &&
46 >junk2 &&
47 git add junk2 &&
48 git commit -m "Second junk"
49 ) &&
50 (
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
55 )
56 '
57
58 test_expect_success 'push fails if submodule commit not on remote' '
59 (
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 ) &&
69 (
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 &&
76
77 # ...or if specified in the configuration..
78 test_must_fail git -c push.recurseSubmodules=check push ../pub.git main
79 )
80 '
81
82 test_expect_success 'push succeeds after commit was pushed to remote' '
83 (
84 cd work/gar/bage &&
85 git push origin main
86 ) &&
87 (
88 cd work &&
89 git push --recurse-submodules=check ../pub.git main
90 )
91 '
92
93 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
94 (
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 ) &&
100 (
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
111 )
112 '
113
114 test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
115 (
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 ) &&
121 (
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
132 )
133 '
134
135 test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
136 (
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 ) &&
142 (
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
153 )
154 '
155
156 test_expect_success 'push recurse-submodules on command line overrides config' '
157 (
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 ) &&
163 (
164 cd work &&
165 git add gar/bage &&
166 git commit -m "Recurse on command-line overriding config for gar/bage" &&
167
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^) &&
176
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^) &&
184
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^) &&
191
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)
198 )
199 '
200
201 test_expect_success 'push recurse-submodules last one wins on command line' '
202 (
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 ) &&
208 (
209 cd work &&
210 git add gar/bage &&
211 git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
212
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^) &&
220
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^) &&
228
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^) &&
233
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)
239 )
240 '
241
242 test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
243 (
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 ) &&
249 (
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
260 )
261 '
262
263 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
264 (
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 ) &&
270 (
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
282 )
283 '
284
285 test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
286 (
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 ) &&
292 (
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
304 )
305 '
306
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
315 '
316
317 test_expect_success 'push fails if recurse submodules option passed as yes' '
318 (
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 ) &&
324 (
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
331 )
332 '
333
334 test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
335 (
336 cd work/gar/bage &&
337 >junk4 &&
338 git add junk4 &&
339 git commit -m "Fourth junk"
340 ) &&
341 (
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 &&
347 (
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
355 )
356 '
357
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 &&
361 (
362 cd a1 &&
363 git init b &&
364 (
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
373 )
374 '
375
376 test_expect_success 'push unpushed submodules when not needed' '
377 (
378 cd work &&
379 (
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 ) &&
393 (
394 cd submodule.git &&
395 git rev-parse main >../actual
396 ) &&
397 test_cmp expected actual
398 '
399
400 test_expect_success 'push unpushed submodules when not needed 2' '
401 (
402 cd submodule.git &&
403 git rev-parse main >../expected
404 ) &&
405 (
406 cd work &&
407 (
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 ) &&
418 (
419 cd submodule.git &&
420 git rev-parse main >../actual
421 ) &&
422 test_cmp expected actual
423 '
424
425 test_expect_success 'push unpushed submodules recursively' '
426 (
427 cd work &&
428 (
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 ) &&
441 (
442 cd submodule.git &&
443 git rev-parse main >../actual
444 ) &&
445 test_cmp expected actual
446 '
447
448 test_expect_success 'push unpushable submodule recursively fails' '
449 (
450 cd work &&
451 (
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 ) &&
463 (
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
469 '
470
471 test_expect_success 'push --dry-run does not recursively update submodules' '
472 (
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" &&
479
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
492 '
493
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 &&
496
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
501 '
502
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 &&
506
507 git -C work push --recurse-submodules=only ../pub.git main &&
508
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
513 '
514
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 &&
524
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
529 }
530
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
537 }
538
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 &&
545
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
549 '
550
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 &&
558
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
563 '
564
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 &&
568
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" &&
574
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 &&
579
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
586 '
587
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" &&
592
593 git -C work checkout branch2 &&
594 git -C work add gar/bage &&
595 git -C work commit -m "updating gar/bage in branch2" &&
596
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 &&
606
607 git -C work/gar/bage branch branch2 main &&
608 git -C work push --recurse-submodules=on-demand origin branch2 &&
609
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
616 '
617
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" &&
623
624 git -C work checkout branch2 &&
625 git -C work add gar/bage &&
626 git -C work commit -m "updating gar/bage in branch2" &&
627
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 &&
631
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
638 '
639
640 test_done