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