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