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