1#!/bin/sh
2#
3# Copyright (c) 2009 Red Hat, Inc.
4#
5
6test_description='Test updating submodules
7
8This test verifies that "git submodule update" detaches the HEAD of the
9submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
10'
11
12. ./test-lib.sh
13
14
15compare_head()
16{
17 sha_master=`git rev-list --max-count=1 master`
18 sha_head=`git rev-list --max-count=1 HEAD`
19
20 test "$sha_master" = "$sha_head"
21}
22
23
24test_expect_success 'setup a submodule tree' '
25 echo file > file &&
26 git add file &&
27 test_tick &&
28 git commit -m upstream &&
29 git clone . super &&
30 git clone super submodule &&
31 git clone super rebasing &&
32 git clone super merging &&
33 git clone super none &&
34 (cd super &&
35 git submodule add ../submodule submodule &&
36 test_tick &&
37 git commit -m "submodule" &&
38 git submodule init submodule
39 ) &&
40 (cd submodule &&
41 echo "line2" > file &&
42 git add file &&
43 git commit -m "Commit 2"
44 ) &&
45 (cd super &&
46 (cd submodule &&
47 git pull --rebase origin
48 ) &&
49 git add submodule &&
50 git commit -m "submodule update"
51 ) &&
52 (cd super &&
53 git submodule add ../rebasing rebasing &&
54 test_tick &&
55 git commit -m "rebasing"
56 ) &&
57 (cd super &&
58 git submodule add ../merging merging &&
59 test_tick &&
60 git commit -m "rebasing"
61 ) &&
62 (cd super &&
63 git submodule add ../none none &&
64 test_tick &&
65 git commit -m "none"
66 )
67'
68
69test_expect_success 'submodule update detaching the HEAD ' '
70 (cd super/submodule &&
71 git reset --hard HEAD~1
72 ) &&
73 (cd super &&
74 (cd submodule &&
75 compare_head
76 ) &&
77 git submodule update submodule &&
78 cd submodule &&
79 ! compare_head
80 )
81'
82
83test_expect_success 'submodule update from subdirectory' '
84 (cd super/submodule &&
85 git reset --hard HEAD~1
86 ) &&
87 mkdir super/sub &&
88 (cd super/sub &&
89 (cd ../submodule &&
90 compare_head
91 ) &&
92 git submodule update ../submodule &&
93 cd ../submodule &&
94 ! compare_head
95 )
96'
97
98apos="'";
99test_expect_success 'submodule update does not fetch already present commits' '
100 (cd submodule &&
101 echo line3 >> file &&
102 git add file &&
103 test_tick &&
104 git commit -m "upstream line3"
105 ) &&
106 (cd super/submodule &&
107 head=$(git rev-parse --verify HEAD) &&
108 echo "Submodule path ${apos}submodule$apos: checked out $apos$head$apos" > ../../expected &&
109 git reset --hard HEAD~1
110 ) &&
111 (cd super &&
112 git submodule update > ../actual 2> ../actual.err
113 ) &&
114 test_i18ncmp expected actual &&
115 ! test -s actual.err
116'
117
118test_expect_success 'submodule update should fail due to local changes' '
119 (cd super/submodule &&
120 git reset --hard HEAD~1 &&
121 echo "local change" > file
122 ) &&
123 (cd super &&
124 (cd submodule &&
125 compare_head
126 ) &&
127 test_must_fail git submodule update submodule
128 )
129'
130test_expect_success 'submodule update should throw away changes with --force ' '
131 (cd super &&
132 (cd submodule &&
133 compare_head
134 ) &&
135 git submodule update --force submodule &&
136 cd submodule &&
137 ! compare_head
138 )
139'
140
141test_expect_success 'submodule update --force forcibly checks out submodules' '
142 (cd super &&
143 (cd submodule &&
144 rm -f file
145 ) &&
146 git submodule update --force submodule &&
147 (cd submodule &&
148 test "$(git status -s file)" = ""
149 )
150 )
151'
152
153test_expect_success 'submodule update --remote should fetch upstream changes' '
154 (cd submodule &&
155 echo line4 >> file &&
156 git add file &&
157 test_tick &&
158 git commit -m "upstream line4"
159 ) &&
160 (cd super &&
161 git submodule update --remote --force submodule &&
162 cd submodule &&
163 test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
164 )
165'
166
167test_expect_success 'local config should override .gitmodules branch' '
168 (cd submodule &&
169 git checkout -b test-branch &&
170 echo line5 >> file &&
171 git add file &&
172 test_tick &&
173 git commit -m "upstream line5" &&
174 git checkout master
175 ) &&
176 (cd super &&
177 git config submodule.submodule.branch test-branch &&
178 git submodule update --remote --force submodule &&
179 cd submodule &&
180 test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
181 )
182'
183
184test_expect_success 'submodule update --rebase staying on master' '
185 (cd super/submodule &&
186 git checkout master
187 ) &&
188 (cd super &&
189 (cd submodule &&
190 compare_head
191 ) &&
192 git submodule update --rebase submodule &&
193 cd submodule &&
194 compare_head
195 )
196'
197
198test_expect_success 'submodule update --merge staying on master' '
199 (cd super/submodule &&
200 git reset --hard HEAD~1
201 ) &&
202 (cd super &&
203 (cd submodule &&
204 compare_head
205 ) &&
206 git submodule update --merge submodule &&
207 cd submodule &&
208 compare_head
209 )
210'
211
212test_expect_success 'submodule update - rebase in .git/config' '
213 (cd super &&
214 git config submodule.submodule.update rebase
215 ) &&
216 (cd super/submodule &&
217 git reset --hard HEAD~1
218 ) &&
219 (cd super &&
220 (cd submodule &&
221 compare_head
222 ) &&
223 git submodule update submodule &&
224 cd submodule &&
225 compare_head
226 )
227'
228
229test_expect_success 'submodule update - checkout in .git/config but --rebase given' '
230 (cd super &&
231 git config submodule.submodule.update checkout
232 ) &&
233 (cd super/submodule &&
234 git reset --hard HEAD~1
235 ) &&
236 (cd super &&
237 (cd submodule &&
238 compare_head
239 ) &&
240 git submodule update --rebase submodule &&
241 cd submodule &&
242 compare_head
243 )
244'
245
246test_expect_success 'submodule update - merge in .git/config' '
247 (cd super &&
248 git config submodule.submodule.update merge
249 ) &&
250 (cd super/submodule &&
251 git reset --hard HEAD~1
252 ) &&
253 (cd super &&
254 (cd submodule &&
255 compare_head
256 ) &&
257 git submodule update submodule &&
258 cd submodule &&
259 compare_head
260 )
261'
262
263test_expect_success 'submodule update - checkout in .git/config but --merge given' '
264 (cd super &&
265 git config submodule.submodule.update checkout
266 ) &&
267 (cd super/submodule &&
268 git reset --hard HEAD~1
269 ) &&
270 (cd super &&
271 (cd submodule &&
272 compare_head
273 ) &&
274 git submodule update --merge submodule &&
275 cd submodule &&
276 compare_head
277 )
278'
279
280test_expect_success 'submodule update - checkout in .git/config' '
281 (cd super &&
282 git config submodule.submodule.update checkout
283 ) &&
284 (cd super/submodule &&
285 git reset --hard HEAD^
286 ) &&
287 (cd super &&
288 (cd submodule &&
289 compare_head
290 ) &&
291 git submodule update submodule &&
292 cd submodule &&
293 ! compare_head
294 )
295'
296
297test_expect_success 'submodule update - command in .git/config' '
298 (cd super &&
299 git config submodule.submodule.update "!git checkout"
300 ) &&
301 (cd super/submodule &&
302 git reset --hard HEAD^
303 ) &&
304 (cd super &&
305 (cd submodule &&
306 compare_head
307 ) &&
308 git submodule update submodule &&
309 cd submodule &&
310 ! compare_head
311 )
312'
313
314test_expect_success 'submodule update - command in .git/config catches failure' '
315 (cd super &&
316 git config submodule.submodule.update "!false"
317 ) &&
318 (cd super/submodule &&
319 git reset --hard HEAD^
320 ) &&
321 (cd super &&
322 test_must_fail git submodule update submodule
323 )
324'
325
326test_expect_success 'submodule init does not copy command into .git/config' '
327 (cd super &&
328 H=$(git ls-files -s submodule | cut -d" " -f2) &&
329 mkdir submodule1 &&
330 git update-index --add --cacheinfo 160000 $H submodule1 &&
331 git config -f .gitmodules submodule.submodule1.path submodule1 &&
332 git config -f .gitmodules submodule.submodule1.url ../submodule &&
333 git config -f .gitmodules submodule.submodule1.update !false &&
334 git submodule init submodule1 &&
335 echo "none" >expect &&
336 git config submodule.submodule1.update >actual &&
337 test_cmp expect actual
338 )
339'
340
341test_expect_success 'submodule init picks up rebase' '
342 (cd super &&
343 git config -f .gitmodules submodule.rebasing.update rebase &&
344 git submodule init rebasing &&
345 test "rebase" = "$(git config submodule.rebasing.update)"
346 )
347'
348
349test_expect_success 'submodule init picks up merge' '
350 (cd super &&
351 git config -f .gitmodules submodule.merging.update merge &&
352 git submodule init merging &&
353 test "merge" = "$(git config submodule.merging.update)"
354 )
355'
356
357test_expect_success 'submodule update --merge - ignores --merge for new submodules' '
358 (cd super &&
359 rm -rf submodule &&
360 git submodule update submodule &&
361 git status -s submodule >expect &&
362 rm -rf submodule &&
363 git submodule update --merge submodule &&
364 git status -s submodule >actual &&
365 test_cmp expect actual
366 )
367'
368
369test_expect_success 'submodule update --rebase - ignores --rebase for new submodules' '
370 (cd super &&
371 rm -rf submodule &&
372 git submodule update submodule &&
373 git status -s submodule >expect &&
374 rm -rf submodule &&
375 git submodule update --rebase submodule &&
376 git status -s submodule >actual &&
377 test_cmp expect actual
378 )
379'
380
381test_expect_success 'submodule update ignores update=merge config for new submodules' '
382 (cd super &&
383 rm -rf submodule &&
384 git submodule update submodule &&
385 git status -s submodule >expect &&
386 rm -rf submodule &&
387 git config submodule.submodule.update merge &&
388 git submodule update submodule &&
389 git status -s submodule >actual &&
390 git config --unset submodule.submodule.update &&
391 test_cmp expect actual
392 )
393'
394
395test_expect_success 'submodule update ignores update=rebase config for new submodules' '
396 (cd super &&
397 rm -rf submodule &&
398 git submodule update submodule &&
399 git status -s submodule >expect &&
400 rm -rf submodule &&
401 git config submodule.submodule.update rebase &&
402 git submodule update submodule &&
403 git status -s submodule >actual &&
404 git config --unset submodule.submodule.update &&
405 test_cmp expect actual
406 )
407'
408
409test_expect_success 'submodule init picks up update=none' '
410 (cd super &&
411 git config -f .gitmodules submodule.none.update none &&
412 git submodule init none &&
413 test "none" = "$(git config submodule.none.update)"
414 )
415'
416
417test_expect_success 'submodule update - update=none in .git/config' '
418 (cd super &&
419 git config submodule.submodule.update none &&
420 (cd submodule &&
421 git checkout master &&
422 compare_head
423 ) &&
424 git diff --raw | grep " submodule" &&
425 git submodule update &&
426 git diff --raw | grep " submodule" &&
427 (cd submodule &&
428 compare_head
429 ) &&
430 git config --unset submodule.submodule.update &&
431 git submodule update submodule
432 )
433'
434
435test_expect_success 'submodule update - update=none in .git/config but --checkout given' '
436 (cd super &&
437 git config submodule.submodule.update none &&
438 (cd submodule &&
439 git checkout master &&
440 compare_head
441 ) &&
442 git diff --raw | grep " submodule" &&
443 git submodule update --checkout &&
444 test_must_fail git diff --raw \| grep " submodule" &&
445 (cd submodule &&
446 test_must_fail compare_head
447 ) &&
448 git config --unset submodule.submodule.update
449 )
450'
451
452test_expect_success 'submodule update --init skips submodule with update=none' '
453 (cd super &&
454 git add .gitmodules &&
455 git commit -m ".gitmodules"
456 ) &&
457 git clone super cloned &&
458 (cd cloned &&
459 git submodule update --init &&
460 test -e submodule/.git &&
461 test_must_fail test -e none/.git
462 )
463'
464
465test_expect_success 'submodule update continues after checkout error' '
466 (cd super &&
467 git reset --hard HEAD &&
468 git submodule add ../submodule submodule2 &&
469 git submodule init &&
470 git commit -am "new_submodule" &&
471 (cd submodule2 &&
472 git rev-parse --verify HEAD >../expect
473 ) &&
474 (cd submodule &&
475 test_commit "update_submodule" file
476 ) &&
477 (cd submodule2 &&
478 test_commit "update_submodule2" file
479 ) &&
480 git add submodule &&
481 git add submodule2 &&
482 git commit -m "two_new_submodule_commits" &&
483 (cd submodule &&
484 echo "" > file
485 ) &&
486 git checkout HEAD^ &&
487 test_must_fail git submodule update &&
488 (cd submodule2 &&
489 git rev-parse --verify HEAD >../actual
490 ) &&
491 test_cmp expect actual
492 )
493'
494test_expect_success 'submodule update continues after recursive checkout error' '
495 (cd super &&
496 git reset --hard HEAD &&
497 git checkout master &&
498 git submodule update &&
499 (cd submodule &&
500 git submodule add ../submodule subsubmodule &&
501 git submodule init &&
502 git commit -m "new_subsubmodule"
503 ) &&
504 git add submodule &&
505 git commit -m "update_submodule" &&
506 (cd submodule &&
507 (cd subsubmodule &&
508 test_commit "update_subsubmodule" file
509 ) &&
510 git add subsubmodule &&
511 test_commit "update_submodule_again" file &&
512 (cd subsubmodule &&
513 test_commit "update_subsubmodule_again" file
514 ) &&
515 test_commit "update_submodule_again_again" file
516 ) &&
517 (cd submodule2 &&
518 git rev-parse --verify HEAD >../expect &&
519 test_commit "update_submodule2_again" file
520 ) &&
521 git add submodule &&
522 git add submodule2 &&
523 git commit -m "new_commits" &&
524 git checkout HEAD^ &&
525 (cd submodule &&
526 git checkout HEAD^ &&
527 (cd subsubmodule &&
528 echo "" > file
529 )
530 ) &&
531 test_must_fail git submodule update --recursive &&
532 (cd submodule2 &&
533 git rev-parse --verify HEAD >../actual
534 ) &&
535 test_cmp expect actual
536 )
537'
538
539test_expect_success 'submodule update exit immediately in case of merge conflict' '
540 (cd super &&
541 git checkout master &&
542 git reset --hard HEAD &&
543 (cd submodule &&
544 (cd subsubmodule &&
545 git reset --hard HEAD
546 )
547 ) &&
548 git submodule update --recursive &&
549 (cd submodule &&
550 test_commit "update_submodule_2" file
551 ) &&
552 (cd submodule2 &&
553 test_commit "update_submodule2_2" file
554 ) &&
555 git add submodule &&
556 git add submodule2 &&
557 git commit -m "two_new_submodule_commits" &&
558 (cd submodule &&
559 git checkout master &&
560 test_commit "conflict" file &&
561 echo "conflict" > file
562 ) &&
563 git checkout HEAD^ &&
564 (cd submodule2 &&
565 git rev-parse --verify HEAD >../expect
566 ) &&
567 git config submodule.submodule.update merge &&
568 test_must_fail git submodule update &&
569 (cd submodule2 &&
570 git rev-parse --verify HEAD >../actual
571 ) &&
572 test_cmp expect actual
573 )
574'
575
576test_expect_success 'submodule update exit immediately after recursive rebase error' '
577 (cd super &&
578 git checkout master &&
579 git reset --hard HEAD &&
580 (cd submodule &&
581 git reset --hard HEAD &&
582 git submodule update --recursive
583 ) &&
584 (cd submodule &&
585 test_commit "update_submodule_3" file
586 ) &&
587 (cd submodule2 &&
588 test_commit "update_submodule2_3" file
589 ) &&
590 git add submodule &&
591 git add submodule2 &&
592 git commit -m "two_new_submodule_commits" &&
593 (cd submodule &&
594 git checkout master &&
595 test_commit "conflict2" file &&
596 echo "conflict" > file
597 ) &&
598 git checkout HEAD^ &&
599 (cd submodule2 &&
600 git rev-parse --verify HEAD >../expect
601 ) &&
602 git config submodule.submodule.update rebase &&
603 test_must_fail git submodule update &&
604 (cd submodule2 &&
605 git rev-parse --verify HEAD >../actual
606 ) &&
607 test_cmp expect actual
608 )
609'
610
611test_expect_success 'add different submodules to the same path' '
612 (cd super &&
613 git submodule add ../submodule s1 &&
614 test_must_fail git submodule add ../merging s1
615 )
616'
617
618test_expect_success 'submodule add places git-dir in superprojects git-dir' '
619 (cd super &&
620 mkdir deeper &&
621 git submodule add ../submodule deeper/submodule &&
622 (cd deeper/submodule &&
623 git log > ../../expected
624 ) &&
625 (cd .git/modules/deeper/submodule &&
626 git log > ../../../../actual
627 ) &&
628 test_cmp actual expected
629 )
630'
631
632test_expect_success 'submodule update places git-dir in superprojects git-dir' '
633 (cd super &&
634 git commit -m "added submodule"
635 ) &&
636 git clone super super2 &&
637 (cd super2 &&
638 git submodule init deeper/submodule &&
639 git submodule update &&
640 (cd deeper/submodule &&
641 git log > ../../expected
642 ) &&
643 (cd .git/modules/deeper/submodule &&
644 git log > ../../../../actual
645 ) &&
646 test_cmp actual expected
647 )
648'
649
650test_expect_success 'submodule add places git-dir in superprojects git-dir recursive' '
651 (cd super2 &&
652 (cd deeper/submodule &&
653 git submodule add ../submodule subsubmodule &&
654 (cd subsubmodule &&
655 git log > ../../../expected
656 ) &&
657 git commit -m "added subsubmodule" &&
658 git push origin :
659 ) &&
660 (cd .git/modules/deeper/submodule/modules/subsubmodule &&
661 git log > ../../../../../actual
662 ) &&
663 git add deeper/submodule &&
664 git commit -m "update submodule" &&
665 git push origin : &&
666 test_cmp actual expected
667 )
668'
669
670test_expect_success 'submodule update places git-dir in superprojects git-dir recursive' '
671 mkdir super_update_r &&
672 (cd super_update_r &&
673 git init --bare
674 ) &&
675 mkdir subsuper_update_r &&
676 (cd subsuper_update_r &&
677 git init --bare
678 ) &&
679 mkdir subsubsuper_update_r &&
680 (cd subsubsuper_update_r &&
681 git init --bare
682 ) &&
683 git clone subsubsuper_update_r subsubsuper_update_r2 &&
684 (cd subsubsuper_update_r2 &&
685 test_commit "update_subsubsuper" file &&
686 git push origin master
687 ) &&
688 git clone subsuper_update_r subsuper_update_r2 &&
689 (cd subsuper_update_r2 &&
690 test_commit "update_subsuper" file &&
691 git submodule add ../subsubsuper_update_r subsubmodule &&
692 git commit -am "subsubmodule" &&
693 git push origin master
694 ) &&
695 git clone super_update_r super_update_r2 &&
696 (cd super_update_r2 &&
697 test_commit "update_super" file &&
698 git submodule add ../subsuper_update_r submodule &&
699 git commit -am "submodule" &&
700 git push origin master
701 ) &&
702 rm -rf super_update_r2 &&
703 git clone super_update_r super_update_r2 &&
704 (cd super_update_r2 &&
705 git submodule update --init --recursive >actual &&
706 test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual &&
707 (cd submodule/subsubmodule &&
708 git log > ../../expected
709 ) &&
710 (cd .git/modules/submodule/modules/subsubmodule
711 git log > ../../../../../actual
712 )
713 test_cmp actual expected
714 )
715'
716
717test_expect_success 'submodule add properly re-creates deeper level submodules' '
718 (cd super &&
719 git reset --hard master &&
720 rm -rf deeper/ &&
721 git submodule add --force ../submodule deeper/submodule
722 )
723'
724
725test_expect_success 'submodule update properly revives a moved submodule' '
726 (cd super &&
727 H=$(git rev-parse --short HEAD) &&
728 git commit -am "pre move" &&
729 H2=$(git rev-parse --short HEAD) &&
730 git status | sed "s/$H/XXX/" >expect &&
731 H=$(cd submodule2; git rev-parse HEAD) &&
732 git rm --cached submodule2 &&
733 rm -rf submodule2 &&
734 mkdir -p "moved/sub module" &&
735 git update-index --add --cacheinfo 160000 $H "moved/sub module" &&
736 git config -f .gitmodules submodule.submodule2.path "moved/sub module"
737 git commit -am "post move" &&
738 git submodule update &&
739 git status | sed "s/$H2/XXX/" >actual &&
740 test_cmp expect actual
741 )
742'
743
744test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd' '
745 mkdir -p linked/dir &&
746 ln -s linked/dir linkto &&
747 (cd linkto &&
748 git clone "$TRASH_DIRECTORY"/super_update_r2 super &&
749 (cd super &&
750 git submodule update --init --recursive
751 )
752 )
753'
754
755test_expect_success 'submodule update clone shallow submodule' '
756 git clone cloned super3 &&
757 pwd=$(pwd) &&
758 (cd super3 &&
759 sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
760 mv -f .gitmodules.tmp .gitmodules &&
761 git submodule update --init --depth=3
762 (cd submodule &&
763 test 1 = $(git log --oneline | wc -l)
764 )
765)
766'
767
768test_expect_success 'submodule update --recursive drops module name before recursing' '
769 (cd super2 &&
770 (cd deeper/submodule/subsubmodule &&
771 git checkout HEAD^
772 ) &&
773 git submodule update --recursive deeper/submodule >actual &&
774 test_i18ngrep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual
775 )
776'
777
778test_expect_success 'submodule update can be run in parallel' '
779 (cd super2 &&
780 GIT_TRACE=$(pwd)/trace.out git submodule update --jobs 7 &&
781 grep "7 tasks" trace.out &&
782 git config submodule.fetchJobs 8 &&
783 GIT_TRACE=$(pwd)/trace.out git submodule update &&
784 grep "8 tasks" trace.out &&
785 GIT_TRACE=$(pwd)/trace.out git submodule update --jobs 9 &&
786 grep "9 tasks" trace.out
787 )
788'
789
790test_expect_success 'git clone passes the parallel jobs config on to submodules' '
791 test_when_finished "rm -rf super4" &&
792 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules --jobs 7 . super4 &&
793 grep "7 tasks" trace.out &&
794 rm -rf super4 &&
795 git config --global submodule.fetchJobs 8 &&
796 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules . super4 &&
797 grep "8 tasks" trace.out &&
798 rm -rf super4 &&
799 GIT_TRACE=$(pwd)/trace.out git clone --recurse-submodules --jobs 9 . super4 &&
800 grep "9 tasks" trace.out &&
801 rm -rf super4
802'
803
804test_done