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