Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2009 Red Hat, Inc.
4 #
5
6 test_description='Test updating submodules
7
8 This test verifies that "git submodule update" detaches the HEAD of the
9 submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
10 '
11
12 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
13 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14
15 . ./test-lib.sh
16
17
18 compare_head()
19 {
20 sha_main=$(git rev-list --max-count=1 main)
21 sha_head=$(git rev-list --max-count=1 HEAD)
22
23 test "$sha_main" = "$sha_head"
24 }
25
26
27 test_expect_success 'setup a submodule tree' '
28 git config --global protocol.file.allow always &&
29 echo file > file &&
30 git add file &&
31 test_tick &&
32 git commit -m upstream &&
33 git clone . super &&
34 git clone super submodule &&
35 git clone super rebasing &&
36 git clone super merging &&
37 git clone super none &&
38 (cd super &&
39 git submodule add ../submodule submodule &&
40 test_tick &&
41 git commit -m "submodule" &&
42 git submodule init submodule
43 ) &&
44 (cd submodule &&
45 echo "line2" > file &&
46 git add file &&
47 git commit -m "Commit 2"
48 ) &&
49 (cd super &&
50 (cd submodule &&
51 git pull --rebase origin
52 ) &&
53 git add submodule &&
54 git commit -m "submodule update"
55 ) &&
56 (cd super &&
57 git submodule add ../rebasing rebasing &&
58 test_tick &&
59 git commit -m "rebasing"
60 ) &&
61 (cd super &&
62 git submodule add ../merging merging &&
63 test_tick &&
64 git commit -m "rebasing"
65 ) &&
66 (cd super &&
67 git submodule add ../none none &&
68 test_tick &&
69 git commit -m "none"
70 ) &&
71 git clone . recursivesuper &&
72 ( cd recursivesuper &&
73 git submodule add ../super super
74 )
75 '
76
77 test_expect_success 'update --remote falls back to using HEAD' '
78 test_create_repo main-branch-submodule &&
79 test_commit -C main-branch-submodule initial &&
80
81 test_create_repo main-branch &&
82 git -C main-branch submodule add ../main-branch-submodule &&
83 git -C main-branch commit -m add-submodule &&
84
85 git -C main-branch-submodule switch -c hello &&
86 test_commit -C main-branch-submodule world &&
87
88 git clone --recursive main-branch main-branch-clone &&
89 git -C main-branch-clone submodule update --remote main-branch-submodule &&
90 test_path_exists main-branch-clone/main-branch-submodule/world.t
91 '
92
93 test_expect_success 'submodule update detaching the HEAD ' '
94 (cd super/submodule &&
95 git reset --hard HEAD~1
96 ) &&
97 (cd super &&
98 (cd submodule &&
99 compare_head
100 ) &&
101 git submodule update submodule &&
102 cd submodule &&
103 ! compare_head
104 )
105 '
106
107 test_expect_success 'submodule update from subdirectory' '
108 (cd super/submodule &&
109 git reset --hard HEAD~1
110 ) &&
111 mkdir super/sub &&
112 (cd super/sub &&
113 (cd ../submodule &&
114 compare_head
115 ) &&
116 git submodule update ../submodule &&
117 cd ../submodule &&
118 ! compare_head
119 )
120 '
121
122 supersha1=$(git -C super rev-parse HEAD)
123 mergingsha1=$(git -C super/merging rev-parse HEAD)
124 nonesha1=$(git -C super/none rev-parse HEAD)
125 rebasingsha1=$(git -C super/rebasing rev-parse HEAD)
126 submodulesha1=$(git -C super/submodule rev-parse HEAD)
127 pwd=$(pwd)
128
129 cat <<EOF >expect
130 Submodule path '../super': checked out '$supersha1'
131 Submodule path '../super/merging': checked out '$mergingsha1'
132 Submodule path '../super/none': checked out '$nonesha1'
133 Submodule path '../super/rebasing': checked out '$rebasingsha1'
134 Submodule path '../super/submodule': checked out '$submodulesha1'
135 EOF
136
137 cat <<EOF >expect2
138 Cloning into '$pwd/recursivesuper/super/merging'...
139 Cloning into '$pwd/recursivesuper/super/none'...
140 Cloning into '$pwd/recursivesuper/super/rebasing'...
141 Cloning into '$pwd/recursivesuper/super/submodule'...
142 Submodule 'merging' ($pwd/merging) registered for path '../super/merging'
143 Submodule 'none' ($pwd/none) registered for path '../super/none'
144 Submodule 'rebasing' ($pwd/rebasing) registered for path '../super/rebasing'
145 Submodule 'submodule' ($pwd/submodule) registered for path '../super/submodule'
146 done.
147 done.
148 done.
149 done.
150 EOF
151
152 test_expect_success 'submodule update --init --recursive from subdirectory' '
153 git -C recursivesuper/super reset --hard HEAD^ &&
154 (cd recursivesuper &&
155 mkdir tmp &&
156 cd tmp &&
157 git submodule update --init --recursive ../super >../../actual 2>../../actual2
158 ) &&
159 test_cmp expect actual &&
160 sort actual2 >actual2.sorted &&
161 test_cmp expect2 actual2.sorted
162 '
163
164 cat <<EOF >expect2
165 Submodule 'foo/sub' ($pwd/withsubs/../rebasing) registered for path 'sub'
166 EOF
167
168 test_expect_success 'submodule update --init from and of subdirectory' '
169 git init withsubs &&
170 (cd withsubs &&
171 mkdir foo &&
172 git submodule add "$(pwd)/../rebasing" foo/sub &&
173 (cd foo &&
174 git submodule deinit -f sub &&
175 git submodule update --init sub 2>../../actual2
176 )
177 ) &&
178 test_cmp expect2 actual2
179 '
180
181 test_expect_success 'submodule update does not fetch already present commits' '
182 (cd submodule &&
183 echo line3 >> file &&
184 git add file &&
185 test_tick &&
186 git commit -m "upstream line3"
187 ) &&
188 (cd super/submodule &&
189 head=$(git rev-parse --verify HEAD) &&
190 echo "Submodule path ${SQ}submodule$SQ: checked out $SQ$head$SQ" > ../../expected &&
191 git reset --hard HEAD~1
192 ) &&
193 (cd super &&
194 git submodule update > ../actual 2> ../actual.err
195 ) &&
196 test_cmp expected actual &&
197 test_must_be_empty actual.err
198 '
199
200 test_expect_success 'submodule update should fail due to local changes' '
201 (cd super/submodule &&
202 git reset --hard HEAD~1 &&
203 echo "local change" > file
204 ) &&
205 (cd super &&
206 (cd submodule &&
207 compare_head
208 ) &&
209 test_must_fail git submodule update submodule 2>../actual.raw
210 ) &&
211 sed "s/^> //" >expect <<-\EOF &&
212 > error: Your local changes to the following files would be overwritten by checkout:
213 > file
214 > Please commit your changes or stash them before you switch branches.
215 > Aborting
216 > fatal: Unable to checkout OID in submodule path '\''submodule'\''
217 EOF
218 sed -e "s/checkout $SQ[^$SQ]*$SQ/checkout OID/" <actual.raw >actual &&
219 test_cmp expect actual
220
221 '
222 test_expect_success 'submodule update should throw away changes with --force ' '
223 (cd super &&
224 (cd submodule &&
225 compare_head
226 ) &&
227 git submodule update --force submodule &&
228 cd submodule &&
229 ! compare_head
230 )
231 '
232
233 test_expect_success 'submodule update --force forcibly checks out submodules' '
234 (cd super &&
235 (cd submodule &&
236 rm -f file
237 ) &&
238 git submodule update --force submodule &&
239 (cd submodule &&
240 test "$(git status -s file)" = ""
241 )
242 )
243 '
244
245 test_expect_success 'submodule update --remote should fetch upstream changes' '
246 (cd submodule &&
247 echo line4 >> file &&
248 git add file &&
249 test_tick &&
250 git commit -m "upstream line4"
251 ) &&
252 (cd super &&
253 git submodule update --remote --force submodule &&
254 cd submodule &&
255 test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
256 )
257 '
258
259 test_expect_success 'submodule update --remote resolves URL rewrites' '
260 test_config_global "url.$(pwd)/.insteadOf" local: &&
261 mkdir alias-super alias-submodule &&
262 (
263 cd alias-submodule &&
264 git init &&
265 git commit --allow-empty --message "Initial commit"
266 ) &&
267 (
268 cd alias-super &&
269 git init &&
270 git submodule add local:alias-submodule submodule &&
271 git submodule update --force &&
272 git -C submodule remote rename origin upstream &&
273 git -C submodule remote add fork user@host &&
274 git submodule update --remote
275 )
276 '
277
278 test_expect_success 'submodule update --remote should fetch upstream changes with .' '
279 (
280 cd super &&
281 git config -f .gitmodules submodule."submodule".branch "." &&
282 git add .gitmodules &&
283 git commit -m "submodules: update from the respective superproject branch"
284 ) &&
285 (
286 cd submodule &&
287 echo line4a >> file &&
288 git add file &&
289 test_tick &&
290 git commit -m "upstream line4a" &&
291 git checkout -b test-branch &&
292 test_commit on-test-branch
293 ) &&
294 (
295 cd super &&
296 git submodule update --remote --force submodule &&
297 git -C submodule log -1 --oneline >actual &&
298 git -C ../submodule log -1 --oneline main >expect &&
299 test_cmp expect actual &&
300 git checkout -b test-branch &&
301 git submodule update --remote --force submodule &&
302 git -C submodule log -1 --oneline >actual &&
303 git -C ../submodule log -1 --oneline test-branch >expect &&
304 test_cmp expect actual &&
305 git checkout main &&
306 git branch -d test-branch &&
307 git reset --hard HEAD^
308 )
309 '
310
311 test_expect_success 'local config should override .gitmodules branch' '
312 (cd submodule &&
313 git checkout test-branch &&
314 echo line5 >> file &&
315 git add file &&
316 test_tick &&
317 git commit -m "upstream line5" &&
318 git checkout main
319 ) &&
320 (cd super &&
321 git config submodule.submodule.branch test-branch &&
322 git submodule update --remote --force submodule &&
323 cd submodule &&
324 test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
325 )
326 '
327
328 test_expect_success 'submodule update --rebase staying on main' '
329 (cd super/submodule &&
330 git checkout main
331 ) &&
332 (cd super &&
333 (cd submodule &&
334 compare_head
335 ) &&
336 git submodule update --rebase submodule &&
337 cd submodule &&
338 compare_head
339 )
340 '
341
342 test_expect_success 'submodule update --merge staying on main' '
343 (cd super/submodule &&
344 git reset --hard HEAD~1
345 ) &&
346 (cd super &&
347 (cd submodule &&
348 compare_head
349 ) &&
350 git submodule update --merge submodule &&
351 cd submodule &&
352 compare_head
353 )
354 '
355
356 test_expect_success 'submodule update - rebase in .git/config' '
357 (cd super &&
358 git config submodule.submodule.update rebase
359 ) &&
360 (cd super/submodule &&
361 git reset --hard HEAD~1
362 ) &&
363 (cd super &&
364 (cd submodule &&
365 compare_head
366 ) &&
367 git submodule update submodule &&
368 cd submodule &&
369 compare_head
370 )
371 '
372
373 test_expect_success 'submodule update - checkout in .git/config but --rebase given' '
374 (cd super &&
375 git config submodule.submodule.update checkout
376 ) &&
377 (cd super/submodule &&
378 git reset --hard HEAD~1
379 ) &&
380 (cd super &&
381 (cd submodule &&
382 compare_head
383 ) &&
384 git submodule update --rebase submodule &&
385 cd submodule &&
386 compare_head
387 )
388 '
389
390 test_expect_success 'submodule update - merge in .git/config' '
391 (cd super &&
392 git config submodule.submodule.update merge
393 ) &&
394 (cd super/submodule &&
395 git reset --hard HEAD~1
396 ) &&
397 (cd super &&
398 (cd submodule &&
399 compare_head
400 ) &&
401 git submodule update submodule &&
402 cd submodule &&
403 compare_head
404 )
405 '
406
407 test_expect_success 'submodule update - checkout in .git/config but --merge given' '
408 (cd super &&
409 git config submodule.submodule.update checkout
410 ) &&
411 (cd super/submodule &&
412 git reset --hard HEAD~1
413 ) &&
414 (cd super &&
415 (cd submodule &&
416 compare_head
417 ) &&
418 git submodule update --merge submodule &&
419 cd submodule &&
420 compare_head
421 )
422 '
423
424 test_expect_success 'submodule update - checkout in .git/config' '
425 (cd super &&
426 git config submodule.submodule.update checkout
427 ) &&
428 (cd super/submodule &&
429 git reset --hard HEAD^
430 ) &&
431 (cd super &&
432 (cd submodule &&
433 compare_head
434 ) &&
435 git submodule update submodule &&
436 cd submodule &&
437 ! compare_head
438 )
439 '
440
441 test_expect_success 'submodule update - command in .git/config' '
442 (cd super &&
443 git config submodule.submodule.update "!git checkout"
444 ) &&
445 (cd super/submodule &&
446 git reset --hard HEAD^
447 ) &&
448 (cd super &&
449 (cd submodule &&
450 compare_head
451 ) &&
452 git submodule update submodule &&
453 cd submodule &&
454 ! compare_head
455 )
456 '
457
458 test_expect_success 'submodule update - command in .gitmodules is rejected' '
459 test_when_finished "git -C super reset --hard HEAD^" &&
460 git -C super config -f .gitmodules submodule.submodule.update "!false" &&
461 git -C super commit -a -m "add command to .gitmodules file" &&
462 git -C super/submodule reset --hard $submodulesha1^ &&
463 test_must_fail git -C super submodule update submodule
464 '
465
466 test_expect_success 'fsck detects command in .gitmodules' '
467 git init command-in-gitmodules &&
468 (
469 cd command-in-gitmodules &&
470 git submodule add ../submodule submodule &&
471 test_commit adding-submodule &&
472
473 git config -f .gitmodules submodule.submodule.update "!false" &&
474 git add .gitmodules &&
475 test_commit configuring-update &&
476 test_must_fail git fsck
477 )
478 '
479
480 cat << EOF >expect
481 fatal: Execution of 'false $submodulesha1' failed in submodule path 'submodule'
482 EOF
483
484 test_expect_success 'submodule update - command in .git/config catches failure' '
485 (cd super &&
486 git config submodule.submodule.update "!false"
487 ) &&
488 (cd super/submodule &&
489 git reset --hard $submodulesha1^
490 ) &&
491 (cd super &&
492 test_must_fail git submodule update submodule 2>../actual
493 ) &&
494 test_cmp actual expect
495 '
496
497 cat << EOF >expect
498 fatal: Execution of 'false $submodulesha1' failed in submodule path '../submodule'
499 EOF
500
501 test_expect_success 'submodule update - command in .git/config catches failure -- subdirectory' '
502 (cd super &&
503 git config submodule.submodule.update "!false"
504 ) &&
505 (cd super/submodule &&
506 git reset --hard $submodulesha1^
507 ) &&
508 (cd super &&
509 mkdir tmp && cd tmp &&
510 test_must_fail git submodule update ../submodule 2>../../actual
511 ) &&
512 test_cmp actual expect
513 '
514
515 test_expect_success 'submodule update - command run for initial population of submodule' '
516 cat >expect <<-EOF &&
517 fatal: Execution of '\''false $submodulesha1'\'' failed in submodule path '\''submodule'\''
518 EOF
519 rm -rf super/submodule &&
520 test_must_fail git -C super submodule update 2>actual &&
521 test_cmp expect actual &&
522 git -C super submodule update --checkout
523 '
524
525 cat << EOF >expect
526 fatal: Execution of 'false $submodulesha1' failed in submodule path '../super/submodule'
527 fatal: Failed to recurse into submodule path '../super'
528 EOF
529
530 test_expect_success 'recursive submodule update - command in .git/config catches failure -- subdirectory' '
531 (cd recursivesuper &&
532 git submodule update --remote super &&
533 git add super &&
534 git commit -m "update to latest to have more than one commit in submodules"
535 ) &&
536 git -C recursivesuper/super config submodule.submodule.update "!false" &&
537 git -C recursivesuper/super/submodule reset --hard $submodulesha1^ &&
538 (cd recursivesuper &&
539 mkdir -p tmp && cd tmp &&
540 test_must_fail git submodule update --recursive ../super 2>../../actual
541 ) &&
542 test_cmp actual expect
543 '
544
545 test_expect_success 'submodule init does not copy command into .git/config' '
546 test_when_finished "git -C super update-index --force-remove submodule1" &&
547 test_when_finished git config -f super/.gitmodules \
548 --remove-section submodule.submodule1 &&
549 (cd super &&
550 git ls-files -s submodule >out &&
551 H=$(cut -d" " -f2 out) &&
552 mkdir submodule1 &&
553 git update-index --add --cacheinfo 160000 $H submodule1 &&
554 git config -f .gitmodules submodule.submodule1.path submodule1 &&
555 git config -f .gitmodules submodule.submodule1.url ../submodule &&
556 git config -f .gitmodules submodule.submodule1.update !false &&
557 test_must_fail git submodule init submodule1 &&
558 test_expect_code 1 git config submodule.submodule1.update >actual &&
559 test_must_be_empty actual
560 )
561 '
562
563 test_expect_success 'submodule init picks up rebase' '
564 (cd super &&
565 git config -f .gitmodules submodule.rebasing.update rebase &&
566 git submodule init rebasing &&
567 test "rebase" = "$(git config submodule.rebasing.update)"
568 )
569 '
570
571 test_expect_success 'submodule init picks up merge' '
572 (cd super &&
573 git config -f .gitmodules submodule.merging.update merge &&
574 git submodule init merging &&
575 test "merge" = "$(git config submodule.merging.update)"
576 )
577 '
578
579 test_expect_success 'submodule update --merge - ignores --merge for new submodules' '
580 test_config -C super submodule.submodule.update checkout &&
581 (cd super &&
582 rm -rf submodule &&
583 git submodule update submodule &&
584 git status -s submodule >expect &&
585 rm -rf submodule &&
586 git submodule update --merge submodule &&
587 git status -s submodule >actual &&
588 test_cmp expect actual
589 )
590 '
591
592 test_expect_success 'submodule update --rebase - ignores --rebase for new submodules' '
593 test_config -C super submodule.submodule.update checkout &&
594 (cd super &&
595 rm -rf submodule &&
596 git submodule update submodule &&
597 git status -s submodule >expect &&
598 rm -rf submodule &&
599 git submodule update --rebase submodule &&
600 git status -s submodule >actual &&
601 test_cmp expect actual
602 )
603 '
604
605 test_expect_success 'submodule update ignores update=merge config for new submodules' '
606 (cd super &&
607 rm -rf submodule &&
608 git submodule update submodule &&
609 git status -s submodule >expect &&
610 rm -rf submodule &&
611 git config submodule.submodule.update merge &&
612 git submodule update submodule &&
613 git status -s submodule >actual &&
614 git config --unset submodule.submodule.update &&
615 test_cmp expect actual
616 )
617 '
618
619 test_expect_success 'submodule update ignores update=rebase config for new submodules' '
620 (cd super &&
621 rm -rf submodule &&
622 git submodule update submodule &&
623 git status -s submodule >expect &&
624 rm -rf submodule &&
625 git config submodule.submodule.update rebase &&
626 git submodule update submodule &&
627 git status -s submodule >actual &&
628 git config --unset submodule.submodule.update &&
629 test_cmp expect actual
630 )
631 '
632
633 test_expect_success 'submodule init picks up update=none' '
634 (cd super &&
635 git config -f .gitmodules submodule.none.update none &&
636 git submodule init none &&
637 test "none" = "$(git config submodule.none.update)"
638 )
639 '
640
641 test_expect_success 'submodule update - update=none in .git/config' '
642 (cd super &&
643 git config submodule.submodule.update none &&
644 (cd submodule &&
645 git checkout main &&
646 compare_head
647 ) &&
648 git diff --name-only >out &&
649 test_grep ^submodule$ out &&
650 git submodule update &&
651 git diff --name-only >out &&
652 test_grep ^submodule$ out &&
653 (cd submodule &&
654 compare_head
655 ) &&
656 git config --unset submodule.submodule.update &&
657 git submodule update submodule
658 )
659 '
660
661 test_expect_success 'submodule update - update=none in .git/config but --checkout given' '
662 (cd super &&
663 git config submodule.submodule.update none &&
664 (cd submodule &&
665 git checkout main &&
666 compare_head
667 ) &&
668 git diff --name-only >out &&
669 test_grep ^submodule$ out &&
670 git submodule update --checkout &&
671 git diff --name-only >out &&
672 test_grep ! ^submodule$ out &&
673 (cd submodule &&
674 ! compare_head
675 ) &&
676 git config --unset submodule.submodule.update
677 )
678 '
679
680 test_expect_success 'submodule update --init skips submodule with update=none' '
681 (cd super &&
682 git add .gitmodules &&
683 git commit -m ".gitmodules"
684 ) &&
685 git clone super cloned &&
686 (cd cloned &&
687 git submodule update --init &&
688 test_path_exists submodule/.git &&
689 test_path_is_missing none/.git
690 )
691 '
692
693 test_expect_success 'submodule update with pathspec warns against uninitialized ones' '
694 test_when_finished "rm -fr selective" &&
695 git clone super selective &&
696 (
697 cd selective &&
698 git submodule init submodule &&
699
700 git submodule update submodule 2>err &&
701 test_grep ! "Submodule path .* not initialized" err &&
702
703 git submodule update rebasing 2>err &&
704 test_grep "Submodule path .rebasing. not initialized" err &&
705
706 test_path_exists submodule/.git &&
707 test_path_is_missing rebasing/.git
708 )
709
710 '
711
712 test_expect_success 'submodule update without pathspec updates only initialized ones' '
713 test_when_finished "rm -fr selective" &&
714 git clone super selective &&
715 (
716 cd selective &&
717 git submodule init submodule &&
718 git submodule update 2>err &&
719 test_path_exists submodule/.git &&
720 test_path_is_missing rebasing/.git &&
721 test_grep ! "Submodule path .* not initialized" err
722 )
723
724 '
725
726 test_expect_success 'submodule update continues after checkout error' '
727 (cd super &&
728 git reset --hard HEAD &&
729 git submodule add ../submodule submodule2 &&
730 git submodule init &&
731 git commit -am "new_submodule" &&
732 (cd submodule2 &&
733 git rev-parse --verify HEAD >../expect
734 ) &&
735 (cd submodule &&
736 test_commit "update_submodule" file
737 ) &&
738 (cd submodule2 &&
739 test_commit "update_submodule2" file
740 ) &&
741 git add submodule &&
742 git add submodule2 &&
743 git commit -m "two_new_submodule_commits" &&
744 (cd submodule &&
745 echo "" > file
746 ) &&
747 git checkout HEAD^ &&
748 test_must_fail git submodule update &&
749 (cd submodule2 &&
750 git rev-parse --verify HEAD >../actual
751 ) &&
752 test_cmp expect actual
753 )
754 '
755 test_expect_success 'submodule update continues after recursive checkout error' '
756 (cd super &&
757 git reset --hard HEAD &&
758 git checkout main &&
759 git submodule update &&
760 (cd submodule &&
761 git submodule add ../submodule subsubmodule &&
762 git submodule init &&
763 git commit -m "new_subsubmodule"
764 ) &&
765 git add submodule &&
766 git commit -m "update_submodule" &&
767 (cd submodule &&
768 (cd subsubmodule &&
769 test_commit "update_subsubmodule" file
770 ) &&
771 git add subsubmodule &&
772 test_commit "update_submodule_again" file &&
773 (cd subsubmodule &&
774 test_commit "update_subsubmodule_again" file
775 ) &&
776 test_commit "update_submodule_again_again" file
777 ) &&
778 (cd submodule2 &&
779 git rev-parse --verify HEAD >../expect &&
780 test_commit "update_submodule2_again" file
781 ) &&
782 git add submodule &&
783 git add submodule2 &&
784 git commit -m "new_commits" &&
785 git checkout HEAD^ &&
786 (cd submodule &&
787 git checkout HEAD^ &&
788 (cd subsubmodule &&
789 echo "" > file
790 )
791 ) &&
792 test_expect_code 1 git submodule update --recursive &&
793 (cd submodule2 &&
794 git rev-parse --verify HEAD >../actual
795 ) &&
796 test_cmp expect actual
797 )
798 '
799
800 test_expect_success 'submodule update exit immediately in case of merge conflict' '
801 (cd super &&
802 git checkout main &&
803 git reset --hard HEAD &&
804 (cd submodule &&
805 (cd subsubmodule &&
806 git reset --hard HEAD
807 )
808 ) &&
809 git submodule update --recursive &&
810 (cd submodule &&
811 test_commit "update_submodule_2" file
812 ) &&
813 (cd submodule2 &&
814 test_commit "update_submodule2_2" file
815 ) &&
816 git add submodule &&
817 git add submodule2 &&
818 git commit -m "two_new_submodule_commits" &&
819 (cd submodule &&
820 git checkout main &&
821 test_commit "conflict" file &&
822 echo "conflict" > file
823 ) &&
824 git checkout HEAD^ &&
825 (cd submodule2 &&
826 git rev-parse --verify HEAD >../expect
827 ) &&
828 git config submodule.submodule.update merge &&
829 test_must_fail git submodule update &&
830 (cd submodule2 &&
831 git rev-parse --verify HEAD >../actual
832 ) &&
833 test_cmp expect actual
834 )
835 '
836
837 test_expect_success 'submodule update exit immediately after recursive rebase error' '
838 (cd super &&
839 git checkout main &&
840 git reset --hard HEAD &&
841 (cd submodule &&
842 git reset --hard HEAD &&
843 git submodule update --recursive
844 ) &&
845 (cd submodule &&
846 test_commit "update_submodule_3" file
847 ) &&
848 (cd submodule2 &&
849 test_commit "update_submodule2_3" file
850 ) &&
851 git add submodule &&
852 git add submodule2 &&
853 git commit -m "two_new_submodule_commits" &&
854 (cd submodule &&
855 git checkout main &&
856 test_commit "conflict2" file &&
857 echo "conflict" > file
858 ) &&
859 git checkout HEAD^ &&
860 (cd submodule2 &&
861 git rev-parse --verify HEAD >../expect
862 ) &&
863 git config submodule.submodule.update rebase &&
864 test_must_fail git submodule update &&
865 (cd submodule2 &&
866 git rev-parse --verify HEAD >../actual
867 ) &&
868 test_cmp expect actual
869 )
870 '
871
872 test_expect_success 'add different submodules to the same path' '
873 (cd super &&
874 git submodule add ../submodule s1 &&
875 test_must_fail git submodule add ../merging s1
876 )
877 '
878
879 test_expect_success 'submodule add places git-dir in superprojects git-dir' '
880 (cd super &&
881 mkdir deeper &&
882 git submodule add ../submodule deeper/submodule &&
883 (cd deeper/submodule &&
884 git log > ../../expected
885 ) &&
886 (cd .git/modules/deeper/submodule &&
887 git log > ../../../../actual
888 ) &&
889 test_cmp expected actual
890 )
891 '
892
893 test_expect_success 'submodule update places git-dir in superprojects git-dir' '
894 (cd super &&
895 git commit -m "added submodule"
896 ) &&
897 git clone super super2 &&
898 (cd super2 &&
899 git submodule init deeper/submodule &&
900 git submodule update &&
901 (cd deeper/submodule &&
902 git log > ../../expected
903 ) &&
904 (cd .git/modules/deeper/submodule &&
905 git log > ../../../../actual
906 ) &&
907 test_cmp expected actual
908 )
909 '
910
911 test_expect_success 'submodule add places git-dir in superprojects git-dir recursive' '
912 (cd super2 &&
913 (cd deeper/submodule &&
914 git submodule add ../submodule subsubmodule &&
915 (cd subsubmodule &&
916 git log > ../../../expected
917 ) &&
918 git commit -m "added subsubmodule" &&
919 git push origin :
920 ) &&
921 (cd .git/modules/deeper/submodule/modules/subsubmodule &&
922 git log > ../../../../../actual
923 ) &&
924 git add deeper/submodule &&
925 git commit -m "update submodule" &&
926 git push origin : &&
927 test_cmp expected actual
928 )
929 '
930
931 test_expect_success 'submodule update places git-dir in superprojects git-dir recursive' '
932 mkdir super_update_r &&
933 (cd super_update_r &&
934 git init --bare
935 ) &&
936 mkdir subsuper_update_r &&
937 (cd subsuper_update_r &&
938 git init --bare
939 ) &&
940 mkdir subsubsuper_update_r &&
941 (cd subsubsuper_update_r &&
942 git init --bare
943 ) &&
944 git clone subsubsuper_update_r subsubsuper_update_r2 &&
945 (cd subsubsuper_update_r2 &&
946 test_commit "update_subsubsuper" file &&
947 git push origin main
948 ) &&
949 git clone subsuper_update_r subsuper_update_r2 &&
950 (cd subsuper_update_r2 &&
951 test_commit "update_subsuper" file &&
952 git submodule add ../subsubsuper_update_r subsubmodule &&
953 git commit -am "subsubmodule" &&
954 git push origin main
955 ) &&
956 git clone super_update_r super_update_r2 &&
957 (cd super_update_r2 &&
958 test_commit "update_super" file &&
959 git submodule add ../subsuper_update_r submodule &&
960 git commit -am "submodule" &&
961 git push origin main
962 ) &&
963 rm -rf super_update_r2 &&
964 git clone super_update_r super_update_r2 &&
965 (cd super_update_r2 &&
966 git submodule update --init --recursive >actual &&
967 test_grep "Submodule path .submodule/subsubmodule.: checked out" actual &&
968 (cd submodule/subsubmodule &&
969 git log > ../../expected
970 ) &&
971 (cd .git/modules/submodule/modules/subsubmodule &&
972 git log > ../../../../../actual
973 ) &&
974 test_cmp expected actual
975 )
976 '
977
978 test_expect_success 'submodule add properly re-creates deeper level submodules' '
979 (cd super &&
980 git reset --hard main &&
981 rm -rf deeper/ &&
982 git submodule add --force ../submodule deeper/submodule
983 )
984 '
985
986 test_expect_success 'submodule update properly revives a moved submodule' '
987 (cd super &&
988 H=$(git rev-parse --short HEAD) &&
989 git commit -am "pre move" &&
990 H2=$(git rev-parse --short HEAD) &&
991 git status >out &&
992 sed "s/$H/XXX/" out >expect &&
993 H=$(cd submodule2 && git rev-parse HEAD) &&
994 git rm --cached submodule2 &&
995 rm -rf submodule2 &&
996 mkdir -p "moved/sub module" &&
997 git update-index --add --cacheinfo 160000 $H "moved/sub module" &&
998 git config -f .gitmodules submodule.submodule2.path "moved/sub module" &&
999 git commit -am "post move" &&
1000 git submodule update &&
1001 git status > out &&
1002 sed "s/$H2/XXX/" out >actual &&
1003 test_cmp expect actual
1004 )
1005 '
1006
1007 test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd' '
1008 mkdir -p linked/dir &&
1009 ln -s linked/dir linkto &&
1010 (cd linkto &&
1011 git clone "$TRASH_DIRECTORY"/super_update_r2 super &&
1012 (cd super &&
1013 git submodule update --init --recursive
1014 )
1015 )
1016 '
1017
1018 test_expect_success 'submodule update clone shallow submodule' '
1019 test_when_finished "rm -rf super3" &&
1020 first=$(git -C cloned rev-parse HEAD:submodule) &&
1021 second=$(git -C submodule rev-parse HEAD) &&
1022 commit_count=$(git -C submodule rev-list --count $first^..$second) &&
1023 git clone cloned super3 &&
1024 pwd=$(pwd) &&
1025 (
1026 cd super3 &&
1027 sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
1028 mv -f .gitmodules.tmp .gitmodules &&
1029 git submodule update --init --depth=$commit_count &&
1030 git -C submodule log --oneline >out &&
1031 test_line_count = 1 out
1032 )
1033 '
1034
1035 test_expect_success 'submodule update clone shallow submodule outside of depth' '
1036 test_when_finished "rm -rf super3" &&
1037 git clone cloned super3 &&
1038 pwd=$(pwd) &&
1039 (
1040 cd super3 &&
1041 sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
1042 mv -f .gitmodules.tmp .gitmodules &&
1043 # Some protocol versions (e.g. 2) support fetching
1044 # unadvertised objects, so restrict this test to v0.
1045 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
1046 git submodule update --init --depth=1 2>actual &&
1047 test_grep "Direct fetching of that commit failed." actual &&
1048 git -C ../submodule config uploadpack.allowReachableSHA1InWant true &&
1049 git submodule update --init --depth=1 >actual &&
1050 git -C submodule log --oneline >out &&
1051 test_line_count = 1 out
1052 )
1053 '
1054
1055 test_expect_success 'submodule update --recursive drops module name before recursing' '
1056 (cd super2 &&
1057 (cd deeper/submodule/subsubmodule &&
1058 git checkout HEAD^
1059 ) &&
1060 git submodule update --recursive deeper/submodule >actual &&
1061 test_grep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual
1062 )
1063 '
1064
1065 test_expect_success 'submodule update can be run in parallel' '
1066 (cd super2 &&
1067 GIT_TRACE=$(pwd)/trace.out git submodule update --jobs 7 &&
1068 test_grep "7 tasks" trace.out &&
1069 git config submodule.fetchJobs 8 &&
1070 GIT_TRACE=$(pwd)/trace.out git submodule update &&
1071 test_grep "8 tasks" trace.out &&
1072 GIT_TRACE=$(pwd)/trace.out git submodule update --jobs 9 &&
1073 test_grep "9 tasks" trace.out
1074 )
1075 '
1076
1077 test_expect_success 'submodule update honors fetch jobs config from .gitmodules' '
1078 test_when_finished "rm -rf super3" &&
1079 git clone cloned super3 &&
1080 git -C super3 config -f .gitmodules submodule.fetchJobs 67 &&
1081 GIT_TRACE="$(pwd)/trace.out" git -C super3 submodule update --init &&
1082 test_grep "67 tasks" trace.out
1083 '
1084
1085 test_expect_success 'git clone passes the parallel jobs config on to submodules' '
1086 test_when_finished "rm -rf super4" &&
1087 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules --jobs 7 . super4 &&
1088 test_grep "7 tasks" trace.out &&
1089 rm -rf super4 &&
1090 git config --global submodule.fetchJobs 8 &&
1091 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules . super4 &&
1092 test_grep "8 tasks" trace.out &&
1093 rm -rf super4 &&
1094 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules --jobs 9 . super4 &&
1095 test_grep "9 tasks" trace.out &&
1096 rm -rf super4
1097 '
1098
1099 test_expect_success 'submodule update --quiet passes quietness to merge/rebase' '
1100 (cd super &&
1101 test_commit -C rebasing message &&
1102 git submodule update --rebase --quiet >out 2>err &&
1103 test_must_be_empty out &&
1104 test_must_be_empty err &&
1105 git submodule update --rebase >out 2>err &&
1106 test_file_not_empty out &&
1107 test_must_be_empty err
1108 )
1109 '
1110
1111 test_expect_success 'submodule update --quiet passes quietness to fetch with a shallow clone' '
1112 test_when_finished "rm -rf super4 super5 super6" &&
1113 git clone . super4 &&
1114 (cd super4 &&
1115 git submodule add --quiet file://"$TRASH_DIRECTORY"/submodule submodule3 &&
1116 git commit -am "setup submodule3"
1117 ) &&
1118 (cd submodule &&
1119 test_commit line6 file
1120 ) &&
1121 git clone super4 super5 &&
1122 (cd super5 &&
1123 # This test var can mess with the stderr output checked in this test.
1124 GIT_TEST_NAME_HASH_VERSION=1 \
1125 GIT_TEST_PACK_PATH_WALK=0 \
1126 git submodule update --quiet --init --depth=1 submodule3 >out 2>err &&
1127 test_must_be_empty out &&
1128 test_must_be_empty err
1129 ) &&
1130 git clone super4 super6 &&
1131 (cd super6 &&
1132 # This test variable will create a "warning" message to stderr
1133 GIT_TEST_PACK_PATH_WALK=0 \
1134 git submodule update --init --depth=1 submodule3 >out 2>err &&
1135 test_file_not_empty out &&
1136 test_file_not_empty err
1137 )
1138 '
1139
1140 test_expect_success 'submodule update --filter requires --init' '
1141 test_expect_code 129 git -C super submodule update --filter blob:none
1142 '
1143
1144 test_expect_success 'submodule update --filter sets partial clone settings' '
1145 test_when_finished "rm -rf super-filter" &&
1146 git clone cloned super-filter &&
1147 git -C super-filter submodule update --init --filter blob:none &&
1148 test_cmp_config -C super-filter/submodule true remote.origin.promisor &&
1149 test_cmp_config -C super-filter/submodule blob:none remote.origin.partialclonefilter
1150 '
1151
1152 # NEEDSWORK: Clean up the tests so that we can reuse the test setup.
1153 # Don't reuse the existing repos because the earlier tests have
1154 # intentionally disruptive configurations.
1155 test_expect_success 'setup clean recursive superproject' '
1156 git init bottom &&
1157 test_commit -C bottom "bottom" &&
1158 git init middle &&
1159 git -C middle submodule add ../bottom bottom &&
1160 git -C middle commit -m "middle" &&
1161 git init top &&
1162 git -C top submodule add ../middle middle &&
1163 git -C top commit -m "top" &&
1164 git clone --recurse-submodules top top-clean
1165 '
1166
1167 test_expect_success 'submodule update with multiple remotes' '
1168 test_when_finished "rm -fr top-cloned" &&
1169 cp -r top-clean top-cloned &&
1170
1171 # Create a commit in each repo, starting with bottom
1172 test_commit -C bottom multiple_remote_commit &&
1173 # Create middle commit
1174 git -C middle/bottom fetch &&
1175 git -C middle/bottom checkout -f FETCH_HEAD &&
1176 git -C middle add bottom &&
1177 git -C middle commit -m "multiple_remote_commit" &&
1178 # Create top commit
1179 git -C top/middle fetch &&
1180 git -C top/middle checkout -f FETCH_HEAD &&
1181 git -C top add middle &&
1182 git -C top commit -m "multiple_remote_commit" &&
1183
1184 # rename the submodule remote
1185 git -C top-cloned/middle remote rename origin upstream &&
1186
1187 # Add another remote
1188 git -C top-cloned/middle remote add other bogus &&
1189
1190 # Make the update of "middle" a no-op, otherwise we error out
1191 # because of its unmerged state
1192 test_config -C top-cloned submodule.middle.update !true &&
1193 git -C top-cloned submodule update --recursive 2>actual.err &&
1194 cat >expect.err <<-\EOF &&
1195 EOF
1196 test_cmp expect.err actual.err
1197 '
1198
1199 test_expect_success 'submodule update with renamed remote' '
1200 test_when_finished "rm -fr top-cloned" &&
1201 cp -r top-clean top-cloned &&
1202
1203 # Create a commit in each repo, starting with bottom
1204 test_commit -C bottom rename_commit &&
1205 # Create middle commit
1206 git -C middle/bottom fetch &&
1207 git -C middle/bottom checkout -f FETCH_HEAD &&
1208 git -C middle add bottom &&
1209 git -C middle commit -m "rename_commit" &&
1210 # Create top commit
1211 git -C top/middle fetch &&
1212 git -C top/middle checkout -f FETCH_HEAD &&
1213 git -C top add middle &&
1214 git -C top commit -m "rename_commit" &&
1215
1216 # rename the submodule remote
1217 git -C top-cloned/middle remote rename origin upstream &&
1218
1219 # Make the update of "middle" a no-op, otherwise we error out
1220 # because of its unmerged state
1221 test_config -C top-cloned submodule.middle.update !true &&
1222 git -C top-cloned submodule update --recursive 2>actual.err &&
1223 cat >expect.err <<-\EOF &&
1224 EOF
1225 test_cmp expect.err actual.err
1226 '
1227
1228 test_expect_success 'submodule update should skip unmerged submodules' '
1229 test_when_finished "rm -fr top-cloned" &&
1230 cp -r top-clean top-cloned &&
1231
1232 # Create an upstream commit in each repo, starting with bottom
1233 test_commit -C bottom upstream_commit &&
1234 # Create middle commit
1235 git -C middle/bottom fetch &&
1236 git -C middle/bottom checkout -f FETCH_HEAD &&
1237 git -C middle add bottom &&
1238 git -C middle commit -m "upstream_commit" &&
1239 # Create top commit
1240 git -C top/middle fetch &&
1241 git -C top/middle checkout -f FETCH_HEAD &&
1242 git -C top add middle &&
1243 git -C top commit -m "upstream_commit" &&
1244
1245 # Create a downstream conflict
1246 test_commit -C top-cloned/middle/bottom downstream_commit &&
1247 git -C top-cloned/middle add bottom &&
1248 git -C top-cloned/middle commit -m "downstream_commit" &&
1249 git -C top-cloned/middle fetch --recurse-submodules origin &&
1250 test_must_fail git -C top-cloned/middle merge origin/main &&
1251
1252 # Make the update of "middle" a no-op, otherwise we error out
1253 # because of its unmerged state
1254 test_config -C top-cloned submodule.middle.update !true &&
1255 git -C top-cloned submodule update --recursive 2>actual.err &&
1256 cat >expect.err <<-\EOF &&
1257 Skipping unmerged submodule middle/bottom
1258 EOF
1259 test_cmp expect.err actual.err
1260 '
1261
1262 test_expect_success 'submodule update --recursive skip submodules with strategy=none' '
1263 test_when_finished "rm -fr top-cloned" &&
1264 cp -r top-clean top-cloned &&
1265
1266 test_commit -C top-cloned/middle/bottom downstream_commit &&
1267 git -C top-cloned/middle config submodule.bottom.update none &&
1268 git -C top-cloned submodule update --recursive 2>actual.err &&
1269 cat >expect.err <<-\EOF &&
1270 Skipping submodule '\''middle/bottom'\''
1271 EOF
1272 test_cmp expect.err actual.err
1273 '
1274
1275 add_submodule_commit_and_validate () {
1276 HASH=$(git rev-parse HEAD) &&
1277 git update-index --add --cacheinfo 160000,$HASH,sub &&
1278 git commit -m "create submodule" &&
1279 echo "160000 commit $HASH sub" >expect &&
1280 git ls-tree HEAD -- sub >actual &&
1281 test_cmp expect actual
1282 }
1283
1284 test_expect_success 'commit with staged submodule change' '
1285 add_submodule_commit_and_validate
1286 '
1287
1288 test_expect_success 'commit with staged submodule change with ignoreSubmodules dirty' '
1289 test_config diff.ignoreSubmodules dirty &&
1290 add_submodule_commit_and_validate
1291 '
1292
1293 test_expect_success 'commit with staged submodule change with ignoreSubmodules all' '
1294 test_config diff.ignoreSubmodules all &&
1295 add_submodule_commit_and_validate
1296 '
1297
1298 test_expect_success CASE_INSENSITIVE_FS,SYMLINKS \
1299 'submodule paths must not follow symlinks' '
1300
1301 # This is only needed because we want to run this in a self-contained
1302 # test without having to spin up an HTTP server; However, it would not
1303 # be needed in a real-world scenario where the submodule is simply
1304 # hosted on a public site.
1305 test_config_global protocol.file.allow always &&
1306
1307 # Make sure that Git tries to use symlinks on Windows
1308 test_config_global core.symlinks true &&
1309
1310 tell_tale_path="$PWD/tell.tale" &&
1311 git init hook &&
1312 (
1313 cd hook &&
1314 mkdir -p y/hooks &&
1315 write_script y/hooks/post-checkout <<-EOF &&
1316 echo HOOK-RUN >&2
1317 echo hook-run >"$tell_tale_path"
1318 EOF
1319 git add y/hooks/post-checkout &&
1320 test_tick &&
1321 git commit -m post-checkout
1322 ) &&
1323
1324 hook_repo_path="$(pwd)/hook" &&
1325 git init captain &&
1326 (
1327 cd captain &&
1328 git submodule add --name x/y "$hook_repo_path" A/modules/x &&
1329 test_tick &&
1330 git commit -m add-submodule &&
1331
1332 printf .git >dotgit.txt &&
1333 git hash-object -w --stdin <dotgit.txt >dot-git.hash &&
1334 printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" >index.info &&
1335 git update-index --index-info <index.info &&
1336 test_tick &&
1337 git commit -m add-symlink
1338 ) &&
1339
1340 test_path_is_missing "$tell_tale_path" &&
1341 git clone --recursive captain hooked 2>err &&
1342 test_grep ! HOOK-RUN err &&
1343 test_path_is_missing "$tell_tale_path"
1344 '
1345
1346 test_done