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