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 picks up rebase' '
327 (cd super &&
328 git config -f .gitmodules submodule.rebasing.update rebase &&
329 git submodule init rebasing &&
330 test "rebase" = "$(git config submodule.rebasing.update)"
331 )
332'
333
334test_expect_success 'submodule init picks up merge' '
335 (cd super &&
336 git config -f .gitmodules submodule.merging.update merge &&
337 git submodule init merging &&
338 test "merge" = "$(git config submodule.merging.update)"
339 )
340'
341
342test_expect_success 'submodule update --merge - ignores --merge for new submodules' '
343 (cd super &&
344 rm -rf submodule &&
345 git submodule update submodule &&
346 git status -s submodule >expect &&
347 rm -rf submodule &&
348 git submodule update --merge submodule &&
349 git status -s submodule >actual &&
350 test_cmp expect actual
351 )
352'
353
354test_expect_success 'submodule update --rebase - ignores --rebase for new submodules' '
355 (cd super &&
356 rm -rf submodule &&
357 git submodule update submodule &&
358 git status -s submodule >expect &&
359 rm -rf submodule &&
360 git submodule update --rebase submodule &&
361 git status -s submodule >actual &&
362 test_cmp expect actual
363 )
364'
365
366test_expect_success 'submodule update ignores update=merge config for new submodules' '
367 (cd super &&
368 rm -rf submodule &&
369 git submodule update submodule &&
370 git status -s submodule >expect &&
371 rm -rf submodule &&
372 git config submodule.submodule.update merge &&
373 git submodule update submodule &&
374 git status -s submodule >actual &&
375 git config --unset submodule.submodule.update &&
376 test_cmp expect actual
377 )
378'
379
380test_expect_success 'submodule update ignores update=rebase config for new submodules' '
381 (cd super &&
382 rm -rf submodule &&
383 git submodule update submodule &&
384 git status -s submodule >expect &&
385 rm -rf submodule &&
386 git config submodule.submodule.update rebase &&
387 git submodule update submodule &&
388 git status -s submodule >actual &&
389 git config --unset submodule.submodule.update &&
390 test_cmp expect actual
391 )
392'
393
394test_expect_success 'submodule init picks up update=none' '
395 (cd super &&
396 git config -f .gitmodules submodule.none.update none &&
397 git submodule init none &&
398 test "none" = "$(git config submodule.none.update)"
399 )
400'
401
402test_expect_success 'submodule update - update=none in .git/config' '
403 (cd super &&
404 git config submodule.submodule.update none &&
405 (cd submodule &&
406 git checkout master &&
407 compare_head
408 ) &&
409 git diff --raw | grep " submodule" &&
410 git submodule update &&
411 git diff --raw | grep " submodule" &&
412 (cd submodule &&
413 compare_head
414 ) &&
415 git config --unset submodule.submodule.update &&
416 git submodule update submodule
417 )
418'
419
420test_expect_success 'submodule update - update=none in .git/config but --checkout given' '
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 --checkout &&
429 test_must_fail git diff --raw \| grep " submodule" &&
430 (cd submodule &&
431 test_must_fail compare_head
432 ) &&
433 git config --unset submodule.submodule.update
434 )
435'
436
437test_expect_success 'submodule update --init skips submodule with update=none' '
438 (cd super &&
439 git add .gitmodules &&
440 git commit -m ".gitmodules"
441 ) &&
442 git clone super cloned &&
443 (cd cloned &&
444 git submodule update --init &&
445 test -e submodule/.git &&
446 test_must_fail test -e none/.git
447 )
448'
449
450test_expect_success 'submodule update continues after checkout error' '
451 (cd super &&
452 git reset --hard HEAD &&
453 git submodule add ../submodule submodule2 &&
454 git submodule init &&
455 git commit -am "new_submodule" &&
456 (cd submodule2 &&
457 git rev-parse --verify HEAD >../expect
458 ) &&
459 (cd submodule &&
460 test_commit "update_submodule" file
461 ) &&
462 (cd submodule2 &&
463 test_commit "update_submodule2" file
464 ) &&
465 git add submodule &&
466 git add submodule2 &&
467 git commit -m "two_new_submodule_commits" &&
468 (cd submodule &&
469 echo "" > file
470 ) &&
471 git checkout HEAD^ &&
472 test_must_fail git submodule update &&
473 (cd submodule2 &&
474 git rev-parse --verify HEAD >../actual
475 ) &&
476 test_cmp expect actual
477 )
478'
479test_expect_success 'submodule update continues after recursive checkout error' '
480 (cd super &&
481 git reset --hard HEAD &&
482 git checkout master &&
483 git submodule update &&
484 (cd submodule &&
485 git submodule add ../submodule subsubmodule &&
486 git submodule init &&
487 git commit -m "new_subsubmodule"
488 ) &&
489 git add submodule &&
490 git commit -m "update_submodule" &&
491 (cd submodule &&
492 (cd subsubmodule &&
493 test_commit "update_subsubmodule" file
494 ) &&
495 git add subsubmodule &&
496 test_commit "update_submodule_again" file &&
497 (cd subsubmodule &&
498 test_commit "update_subsubmodule_again" file
499 ) &&
500 test_commit "update_submodule_again_again" file
501 ) &&
502 (cd submodule2 &&
503 git rev-parse --verify HEAD >../expect &&
504 test_commit "update_submodule2_again" file
505 ) &&
506 git add submodule &&
507 git add submodule2 &&
508 git commit -m "new_commits" &&
509 git checkout HEAD^ &&
510 (cd submodule &&
511 git checkout HEAD^ &&
512 (cd subsubmodule &&
513 echo "" > file
514 )
515 ) &&
516 test_must_fail git submodule update --recursive &&
517 (cd submodule2 &&
518 git rev-parse --verify HEAD >../actual
519 ) &&
520 test_cmp expect actual
521 )
522'
523
524test_expect_success 'submodule update exit immediately in case of merge conflict' '
525 (cd super &&
526 git checkout master &&
527 git reset --hard HEAD &&
528 (cd submodule &&
529 (cd subsubmodule &&
530 git reset --hard HEAD
531 )
532 ) &&
533 git submodule update --recursive &&
534 (cd submodule &&
535 test_commit "update_submodule_2" file
536 ) &&
537 (cd submodule2 &&
538 test_commit "update_submodule2_2" file
539 ) &&
540 git add submodule &&
541 git add submodule2 &&
542 git commit -m "two_new_submodule_commits" &&
543 (cd submodule &&
544 git checkout master &&
545 test_commit "conflict" file &&
546 echo "conflict" > file
547 ) &&
548 git checkout HEAD^ &&
549 (cd submodule2 &&
550 git rev-parse --verify HEAD >../expect
551 ) &&
552 git config submodule.submodule.update merge &&
553 test_must_fail git submodule update &&
554 (cd submodule2 &&
555 git rev-parse --verify HEAD >../actual
556 ) &&
557 test_cmp expect actual
558 )
559'
560
561test_expect_success 'submodule update exit immediately after recursive rebase error' '
562 (cd super &&
563 git checkout master &&
564 git reset --hard HEAD &&
565 (cd submodule &&
566 git reset --hard HEAD &&
567 git submodule update --recursive
568 ) &&
569 (cd submodule &&
570 test_commit "update_submodule_3" file
571 ) &&
572 (cd submodule2 &&
573 test_commit "update_submodule2_3" file
574 ) &&
575 git add submodule &&
576 git add submodule2 &&
577 git commit -m "two_new_submodule_commits" &&
578 (cd submodule &&
579 git checkout master &&
580 test_commit "conflict2" file &&
581 echo "conflict" > file
582 ) &&
583 git checkout HEAD^ &&
584 (cd submodule2 &&
585 git rev-parse --verify HEAD >../expect
586 ) &&
587 git config submodule.submodule.update rebase &&
588 test_must_fail git submodule update &&
589 (cd submodule2 &&
590 git rev-parse --verify HEAD >../actual
591 ) &&
592 test_cmp expect actual
593 )
594'
595
596test_expect_success 'add different submodules to the same path' '
597 (cd super &&
598 git submodule add ../submodule s1 &&
599 test_must_fail git submodule add ../merging s1
600 )
601'
602
603test_expect_success 'submodule add places git-dir in superprojects git-dir' '
604 (cd super &&
605 mkdir deeper &&
606 git submodule add ../submodule deeper/submodule &&
607 (cd deeper/submodule &&
608 git log > ../../expected
609 ) &&
610 (cd .git/modules/deeper/submodule &&
611 git log > ../../../../actual
612 ) &&
613 test_cmp actual expected
614 )
615'
616
617test_expect_success 'submodule update places git-dir in superprojects git-dir' '
618 (cd super &&
619 git commit -m "added submodule"
620 ) &&
621 git clone super super2 &&
622 (cd super2 &&
623 git submodule init deeper/submodule &&
624 git submodule update &&
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 add places git-dir in superprojects git-dir recursive' '
636 (cd super2 &&
637 (cd deeper/submodule &&
638 git submodule add ../submodule subsubmodule &&
639 (cd subsubmodule &&
640 git log > ../../../expected
641 ) &&
642 git commit -m "added subsubmodule" &&
643 git push origin :
644 ) &&
645 (cd .git/modules/deeper/submodule/modules/subsubmodule &&
646 git log > ../../../../../actual
647 ) &&
648 git add deeper/submodule &&
649 git commit -m "update submodule" &&
650 git push origin : &&
651 test_cmp actual expected
652 )
653'
654
655test_expect_success 'submodule update places git-dir in superprojects git-dir recursive' '
656 mkdir super_update_r &&
657 (cd super_update_r &&
658 git init --bare
659 ) &&
660 mkdir subsuper_update_r &&
661 (cd subsuper_update_r &&
662 git init --bare
663 ) &&
664 mkdir subsubsuper_update_r &&
665 (cd subsubsuper_update_r &&
666 git init --bare
667 ) &&
668 git clone subsubsuper_update_r subsubsuper_update_r2 &&
669 (cd subsubsuper_update_r2 &&
670 test_commit "update_subsubsuper" file &&
671 git push origin master
672 ) &&
673 git clone subsuper_update_r subsuper_update_r2 &&
674 (cd subsuper_update_r2 &&
675 test_commit "update_subsuper" file &&
676 git submodule add ../subsubsuper_update_r subsubmodule &&
677 git commit -am "subsubmodule" &&
678 git push origin master
679 ) &&
680 git clone super_update_r super_update_r2 &&
681 (cd super_update_r2 &&
682 test_commit "update_super" file &&
683 git submodule add ../subsuper_update_r submodule &&
684 git commit -am "submodule" &&
685 git push origin master
686 ) &&
687 rm -rf super_update_r2 &&
688 git clone super_update_r super_update_r2 &&
689 (cd super_update_r2 &&
690 git submodule update --init --recursive >actual &&
691 test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual &&
692 (cd submodule/subsubmodule &&
693 git log > ../../expected
694 ) &&
695 (cd .git/modules/submodule/modules/subsubmodule
696 git log > ../../../../../actual
697 )
698 test_cmp actual expected
699 )
700'
701
702test_expect_success 'submodule add properly re-creates deeper level submodules' '
703 (cd super &&
704 git reset --hard master &&
705 rm -rf deeper/ &&
706 git submodule add --force ../submodule deeper/submodule
707 )
708'
709
710test_expect_success 'submodule update properly revives a moved submodule' '
711 (cd super &&
712 H=$(git rev-parse --short HEAD) &&
713 git commit -am "pre move" &&
714 H2=$(git rev-parse --short HEAD) &&
715 git status | sed "s/$H/XXX/" >expect &&
716 H=$(cd submodule2; git rev-parse HEAD) &&
717 git rm --cached submodule2 &&
718 rm -rf submodule2 &&
719 mkdir -p "moved/sub module" &&
720 git update-index --add --cacheinfo 160000 $H "moved/sub module" &&
721 git config -f .gitmodules submodule.submodule2.path "moved/sub module"
722 git commit -am "post move" &&
723 git submodule update &&
724 git status | sed "s/$H2/XXX/" >actual &&
725 test_cmp expect actual
726 )
727'
728
729test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd' '
730 mkdir -p linked/dir &&
731 ln -s linked/dir linkto &&
732 (cd linkto &&
733 git clone "$TRASH_DIRECTORY"/super_update_r2 super &&
734 (cd super &&
735 git submodule update --init --recursive
736 )
737 )
738'
739
740test_expect_success 'submodule update clone shallow submodule' '
741 git clone cloned super3 &&
742 pwd=$(pwd)
743 (cd super3 &&
744 sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
745 mv -f .gitmodules.tmp .gitmodules &&
746 git submodule update --init --depth=3
747 (cd submodule &&
748 test 1 = $(git log --oneline | wc -l)
749 )
750 )
751'
752test_done