1#!/bin/sh
2#
3# Copyright (c) 2007 Lars Hjemli
4#
5
6test_description='Basic porcelain support for submodules
7
8This test tries to verify basic sanity of the init, update and status
9subcommands of git submodule.
10'
11
12. ./test-lib.sh
13
14test_expect_success 'setup - initial commit' '
15 >t &&
16 git add t &&
17 git commit -m "initial commit" &&
18 git branch initial
19'
20
21test_expect_success 'submodule init aborts on missing .gitmodules file' '
22 test_when_finished "git update-index --remove sub" &&
23 git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
24 # missing the .gitmodules file here
25 test_must_fail git submodule init 2>actual &&
26 test_i18ngrep "No url found for submodule path" actual
27'
28
29test_expect_success 'submodule update aborts on missing .gitmodules file' '
30 test_when_finished "git update-index --remove sub" &&
31 git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
32 # missing the .gitmodules file here
33 git submodule update sub 2>actual &&
34 test_i18ngrep "Submodule path .sub. not initialized" actual
35'
36
37test_expect_success 'configuration parsing' '
38 test_when_finished "rm -f .gitmodules" &&
39 cat >.gitmodules <<-\EOF &&
40 [submodule "s"]
41 path
42 ignore
43 EOF
44 test_must_fail git status
45'
46
47test_expect_success 'setup - repository in init subdirectory' '
48 mkdir init &&
49 (
50 cd init &&
51 git init &&
52 echo a >a &&
53 git add a &&
54 git commit -m "submodule commit 1" &&
55 git tag -a -m "rev-1" rev-1
56 )
57'
58
59test_expect_success 'setup - commit with gitlink' '
60 echo a >a &&
61 echo z >z &&
62 git add a init z &&
63 git commit -m "super commit 1"
64'
65
66test_expect_success 'setup - hide init subdirectory' '
67 mv init .subrepo
68'
69
70test_expect_success 'setup - repository to add submodules to' '
71 git init addtest &&
72 git init addtest-ignore
73'
74
75# The 'submodule add' tests need some repository to add as a submodule.
76# The trash directory is a good one as any. We need to canonicalize
77# the name, though, as some tests compare it to the absolute path git
78# generates, which will expand symbolic links.
79submodurl=$(pwd -P)
80
81listbranches() {
82 git for-each-ref --format='%(refname)' 'refs/heads/*'
83}
84
85inspect() {
86 dir=$1 &&
87 dotdot="${2:-..}" &&
88
89 (
90 cd "$dir" &&
91 listbranches >"$dotdot/heads" &&
92 { git symbolic-ref HEAD || :; } >"$dotdot/head" &&
93 git rev-parse HEAD >"$dotdot/head-sha1" &&
94 git update-index --refresh &&
95 git diff-files --exit-code &&
96 git clean -n -d -x >"$dotdot/untracked"
97 )
98}
99
100test_expect_success 'submodule add' '
101 echo "refs/heads/master" >expect &&
102 >empty &&
103
104 (
105 cd addtest &&
106 git submodule add -q "$submodurl" submod >actual &&
107 test_must_be_empty actual &&
108 echo "gitdir: ../.git/modules/submod" >expect &&
109 test_cmp expect submod/.git &&
110 (
111 cd submod &&
112 git config core.worktree >actual &&
113 echo "../../../submod" >expect &&
114 test_cmp expect actual &&
115 rm -f actual expect
116 ) &&
117 git submodule init
118 ) &&
119
120 rm -f heads head untracked &&
121 inspect addtest/submod ../.. &&
122 test_cmp expect heads &&
123 test_cmp expect head &&
124 test_cmp empty untracked
125'
126
127test_expect_success 'submodule add to .gitignored path fails' '
128 (
129 cd addtest-ignore &&
130 cat <<-\EOF >expect &&
131 The following path is ignored by one of your .gitignore files:
132 submod
133 Use -f if you really want to add it.
134 EOF
135 # Does not use test_commit due to the ignore
136 echo "*" > .gitignore &&
137 git add --force .gitignore &&
138 git commit -m"Ignore everything" &&
139 ! git submodule add "$submodurl" submod >actual 2>&1 &&
140 test_i18ncmp expect actual
141 )
142'
143
144test_expect_success 'submodule add to .gitignored path with --force' '
145 (
146 cd addtest-ignore &&
147 git submodule add --force "$submodurl" submod
148 )
149'
150
151test_expect_success 'submodule add --branch' '
152 echo "refs/heads/initial" >expect-head &&
153 cat <<-\EOF >expect-heads &&
154 refs/heads/initial
155 refs/heads/master
156 EOF
157 >empty &&
158
159 (
160 cd addtest &&
161 git submodule add -b initial "$submodurl" submod-branch &&
162 test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
163 git submodule init
164 ) &&
165
166 rm -f heads head untracked &&
167 inspect addtest/submod-branch ../.. &&
168 test_cmp expect-heads heads &&
169 test_cmp expect-head head &&
170 test_cmp empty untracked
171'
172
173test_expect_success 'submodule add with ./ in path' '
174 echo "refs/heads/master" >expect &&
175 >empty &&
176
177 (
178 cd addtest &&
179 git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
180 git submodule init
181 ) &&
182
183 rm -f heads head untracked &&
184 inspect addtest/dotsubmod/frotz ../../.. &&
185 test_cmp expect heads &&
186 test_cmp expect head &&
187 test_cmp empty untracked
188'
189
190test_expect_success 'submodule add with /././ in path' '
191 echo "refs/heads/master" >expect &&
192 >empty &&
193
194 (
195 cd addtest &&
196 git submodule add "$submodurl" dotslashdotsubmod/././frotz/./ &&
197 git submodule init
198 ) &&
199
200 rm -f heads head untracked &&
201 inspect addtest/dotslashdotsubmod/frotz ../../.. &&
202 test_cmp expect heads &&
203 test_cmp expect head &&
204 test_cmp empty untracked
205'
206
207test_expect_success 'submodule add with // in path' '
208 echo "refs/heads/master" >expect &&
209 >empty &&
210
211 (
212 cd addtest &&
213 git submodule add "$submodurl" slashslashsubmod///frotz// &&
214 git submodule init
215 ) &&
216
217 rm -f heads head untracked &&
218 inspect addtest/slashslashsubmod/frotz ../../.. &&
219 test_cmp expect heads &&
220 test_cmp expect head &&
221 test_cmp empty untracked
222'
223
224test_expect_success 'submodule add with /.. in path' '
225 echo "refs/heads/master" >expect &&
226 >empty &&
227
228 (
229 cd addtest &&
230 git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
231 git submodule init
232 ) &&
233
234 rm -f heads head untracked &&
235 inspect addtest/realsubmod ../.. &&
236 test_cmp expect heads &&
237 test_cmp expect head &&
238 test_cmp empty untracked
239'
240
241test_expect_success 'submodule add with ./, /.. and // in path' '
242 echo "refs/heads/master" >expect &&
243 >empty &&
244
245 (
246 cd addtest &&
247 git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
248 git submodule init
249 ) &&
250
251 rm -f heads head untracked &&
252 inspect addtest/realsubmod2 ../.. &&
253 test_cmp expect heads &&
254 test_cmp expect head &&
255 test_cmp empty untracked
256'
257
258test_expect_success 'submodule add in subdirectory' '
259 echo "refs/heads/master" >expect &&
260 >empty &&
261
262 mkdir addtest/sub &&
263 (
264 cd addtest/sub &&
265 git submodule add "$submodurl" ../realsubmod3 &&
266 git submodule init
267 ) &&
268
269 rm -f heads head untracked &&
270 inspect addtest/realsubmod3 ../.. &&
271 test_cmp expect heads &&
272 test_cmp expect head &&
273 test_cmp empty untracked
274'
275
276test_expect_success 'submodule add in subdirectory with relative path should fail' '
277 (
278 cd addtest/sub &&
279 test_must_fail git submodule add ../../ submod3 2>../../output.err
280 ) &&
281 test_i18ngrep toplevel output.err
282'
283
284test_expect_success 'setup - add an example entry to .gitmodules' '
285 git config --file=.gitmodules submodule.example.url git://example.com/init.git
286'
287
288test_expect_success 'status should fail for unmapped paths' '
289 test_must_fail git submodule status
290'
291
292test_expect_success 'setup - map path in .gitmodules' '
293 cat <<\EOF >expect &&
294[submodule "example"]
295 url = git://example.com/init.git
296 path = init
297EOF
298
299 git config --file=.gitmodules submodule.example.path init &&
300
301 test_cmp expect .gitmodules
302'
303
304test_expect_success 'status should only print one line' '
305 git submodule status >lines &&
306 test_line_count = 1 lines
307'
308
309test_expect_success 'setup - fetch commit name from submodule' '
310 rev1=$(cd .subrepo && git rev-parse HEAD) &&
311 printf "rev1: %s\n" "$rev1" &&
312 test -n "$rev1"
313'
314
315test_expect_success 'status should initially be "missing"' '
316 git submodule status >lines &&
317 grep "^-$rev1" lines
318'
319
320test_expect_success 'init should register submodule url in .git/config' '
321 echo git://example.com/init.git >expect &&
322
323 git submodule init &&
324 git config submodule.example.url >url &&
325 git config submodule.example.url ./.subrepo &&
326
327 test_cmp expect url
328'
329
330test_failure_with_unknown_submodule () {
331 test_must_fail git submodule $1 no-such-submodule 2>output.err &&
332 grep "^error: .*no-such-submodule" output.err
333}
334
335test_expect_success 'init should fail with unknown submodule' '
336 test_failure_with_unknown_submodule init
337'
338
339test_expect_success 'update should fail with unknown submodule' '
340 test_failure_with_unknown_submodule update
341'
342
343test_expect_success 'status should fail with unknown submodule' '
344 test_failure_with_unknown_submodule status
345'
346
347test_expect_success 'sync should fail with unknown submodule' '
348 test_failure_with_unknown_submodule sync
349'
350
351test_expect_success 'update should fail when path is used by a file' '
352 echo hello >expect &&
353
354 echo "hello" >init &&
355 test_must_fail git submodule update &&
356
357 test_cmp expect init
358'
359
360test_expect_success 'update should fail when path is used by a nonempty directory' '
361 echo hello >expect &&
362
363 rm -fr init &&
364 mkdir init &&
365 echo "hello" >init/a &&
366
367 test_must_fail git submodule update &&
368
369 test_cmp expect init/a
370'
371
372test_expect_success 'update should work when path is an empty dir' '
373 rm -fr init &&
374 rm -f head-sha1 &&
375 echo "$rev1" >expect &&
376
377 mkdir init &&
378 git submodule update -q >update.out &&
379 test_must_be_empty update.out &&
380
381 inspect init &&
382 test_cmp expect head-sha1
383'
384
385test_expect_success 'status should be "up-to-date" after update' '
386 git submodule status >list &&
387 grep "^ $rev1" list
388'
389
390test_expect_success 'status "up-to-date" from subdirectory' '
391 mkdir -p sub &&
392 (
393 cd sub &&
394 git submodule status >../list
395 ) &&
396 grep "^ $rev1" list &&
397 grep "\\.\\./init" list
398'
399
400test_expect_success 'status "up-to-date" from subdirectory with path' '
401 mkdir -p sub &&
402 (
403 cd sub &&
404 git submodule status ../init >../list
405 ) &&
406 grep "^ $rev1" list &&
407 grep "\\.\\./init" list
408'
409
410test_expect_success 'status should be "modified" after submodule commit' '
411 (
412 cd init &&
413 echo b >b &&
414 git add b &&
415 git commit -m "submodule commit 2"
416 ) &&
417
418 rev2=$(cd init && git rev-parse HEAD) &&
419 test -n "$rev2" &&
420 git submodule status >list &&
421
422 grep "^+$rev2" list
423'
424
425test_expect_success 'the --cached sha1 should be rev1' '
426 git submodule --cached status >list &&
427 grep "^+$rev1" list
428'
429
430test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
431 git diff >diff &&
432 grep "^+Subproject commit $rev2" diff
433'
434
435test_expect_success 'update should checkout rev1' '
436 rm -f head-sha1 &&
437 echo "$rev1" >expect &&
438
439 git submodule update init &&
440 inspect init &&
441
442 test_cmp expect head-sha1
443'
444
445test_expect_success 'status should be "up-to-date" after update' '
446 git submodule status >list &&
447 grep "^ $rev1" list
448'
449
450test_expect_success 'checkout superproject with subproject already present' '
451 git checkout initial &&
452 git checkout master
453'
454
455test_expect_success 'apply submodule diff' '
456 >empty &&
457
458 git branch second &&
459 (
460 cd init &&
461 echo s >s &&
462 git add s &&
463 git commit -m "change subproject"
464 ) &&
465 git update-index --add init &&
466 git commit -m "change init" &&
467 git format-patch -1 --stdout >P.diff &&
468 git checkout second &&
469 git apply --index P.diff &&
470
471 git diff --cached master >staged &&
472 test_cmp empty staged
473'
474
475test_expect_success 'update --init' '
476 mv init init2 &&
477 git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
478 git config --remove-section submodule.example &&
479 test_must_fail git config submodule.example.url &&
480
481 git submodule update init 2> update.out &&
482 cat update.out &&
483 test_i18ngrep "not initialized" update.out &&
484 test_must_fail git rev-parse --resolve-git-dir init/.git &&
485
486 git submodule update --init init &&
487 git rev-parse --resolve-git-dir init/.git
488'
489
490test_expect_success 'update --init from subdirectory' '
491 mv init init2 &&
492 git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
493 git config --remove-section submodule.example &&
494 test_must_fail git config submodule.example.url &&
495
496 mkdir -p sub &&
497 (
498 cd sub &&
499 git submodule update ../init 2>update.out &&
500 cat update.out &&
501 test_i18ngrep "not initialized" update.out &&
502 test_must_fail git rev-parse --resolve-git-dir ../init/.git &&
503
504 git submodule update --init ../init
505 ) &&
506 git rev-parse --resolve-git-dir init/.git
507'
508
509test_expect_success 'do not add files from a submodule' '
510
511 git reset --hard &&
512 test_must_fail git add init/a
513
514'
515
516test_expect_success 'gracefully add/reset submodule with a trailing slash' '
517
518 git reset --hard &&
519 git commit -m "commit subproject" init &&
520 (cd init &&
521 echo b > a) &&
522 git add init/ &&
523 git diff --exit-code --cached init &&
524 commit=$(cd init &&
525 git commit -m update a >/dev/null &&
526 git rev-parse HEAD) &&
527 git add init/ &&
528 test_must_fail git diff --exit-code --cached init &&
529 test $commit = $(git ls-files --stage |
530 sed -n "s/^160000 \([^ ]*\).*/\1/p") &&
531 git reset init/ &&
532 git diff --exit-code --cached init
533
534'
535
536test_expect_success 'ls-files gracefully handles trailing slash' '
537
538 test "init" = "$(git ls-files init/)"
539
540'
541
542test_expect_success 'moving to a commit without submodule does not leave empty dir' '
543 rm -rf init &&
544 mkdir init &&
545 git reset --hard &&
546 git checkout initial &&
547 test ! -d init &&
548 git checkout second
549'
550
551test_expect_success 'submodule <invalid-subcommand> fails' '
552 test_must_fail git submodule no-such-subcommand
553'
554
555test_expect_success 'add submodules without specifying an explicit path' '
556 mkdir repo &&
557 (
558 cd repo &&
559 git init &&
560 echo r >r &&
561 git add r &&
562 git commit -m "repo commit 1"
563 ) &&
564 git clone --bare repo/ bare.git &&
565 (
566 cd addtest &&
567 git submodule add "$submodurl/repo" &&
568 git config -f .gitmodules submodule.repo.path repo &&
569 git submodule add "$submodurl/bare.git" &&
570 git config -f .gitmodules submodule.bare.path bare
571 )
572'
573
574test_expect_success 'add should fail when path is used by a file' '
575 (
576 cd addtest &&
577 touch file &&
578 test_must_fail git submodule add "$submodurl/repo" file
579 )
580'
581
582test_expect_success 'add should fail when path is used by an existing directory' '
583 (
584 cd addtest &&
585 mkdir empty-dir &&
586 test_must_fail git submodule add "$submodurl/repo" empty-dir
587 )
588'
589
590test_expect_success 'use superproject as upstream when path is relative and no url is set there' '
591 (
592 cd addtest &&
593 git submodule add ../repo relative &&
594 test "$(git config -f .gitmodules submodule.relative.url)" = ../repo &&
595 git submodule sync relative &&
596 test "$(git config submodule.relative.url)" = "$submodurl/repo"
597 )
598'
599
600test_expect_success 'set up for relative path tests' '
601 mkdir reltest &&
602 (
603 cd reltest &&
604 git init &&
605 mkdir sub &&
606 (
607 cd sub &&
608 git init &&
609 test_commit foo
610 ) &&
611 git add sub &&
612 git config -f .gitmodules submodule.sub.path sub &&
613 git config -f .gitmodules submodule.sub.url ../subrepo &&
614 cp .git/config pristine-.git-config &&
615 cp .gitmodules pristine-.gitmodules
616 )
617'
618
619test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
620 (
621 cd reltest &&
622 cp pristine-.git-config .git/config &&
623 cp pristine-.gitmodules .gitmodules &&
624 git config remote.origin.url ssh://hostname/repo &&
625 git submodule init &&
626 test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
627 )
628'
629
630test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
631 (
632 cd reltest &&
633 cp pristine-.git-config .git/config &&
634 cp pristine-.gitmodules .gitmodules &&
635 git config remote.origin.url ssh://hostname:22/repo &&
636 git submodule init &&
637 test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
638 )
639'
640
641# About the choice of the path in the next test:
642# - double-slash side-steps path mangling issues on Windows
643# - it is still an absolute local path
644# - there cannot be a server with a blank in its name just in case the
645# path is used erroneously to access a //server/share style path
646test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
647 (
648 cd reltest &&
649 cp pristine-.git-config .git/config &&
650 cp pristine-.gitmodules .gitmodules &&
651 git config remote.origin.url "//somewhere else/repo" &&
652 git submodule init &&
653 test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
654 )
655'
656
657test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
658 (
659 cd reltest &&
660 cp pristine-.git-config .git/config &&
661 cp pristine-.gitmodules .gitmodules &&
662 git config remote.origin.url file:///tmp/repo &&
663 git submodule init &&
664 test "$(git config submodule.sub.url)" = file:///tmp/subrepo
665 )
666'
667
668test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
669 (
670 cd reltest &&
671 cp pristine-.git-config .git/config &&
672 cp pristine-.gitmodules .gitmodules &&
673 git config remote.origin.url helper:://hostname/repo &&
674 git submodule init &&
675 test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
676 )
677'
678
679test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
680 (
681 cd reltest &&
682 cp pristine-.git-config .git/config &&
683 git config remote.origin.url user@host:repo &&
684 git submodule init &&
685 test "$(git config submodule.sub.url)" = user@host:subrepo
686 )
687'
688
689test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
690 (
691 cd reltest &&
692 cp pristine-.git-config .git/config &&
693 cp pristine-.gitmodules .gitmodules &&
694 git config remote.origin.url user@host:path/to/repo &&
695 git submodule init &&
696 test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
697 )
698'
699
700test_expect_success '../subrepo works with relative local path - foo' '
701 (
702 cd reltest &&
703 cp pristine-.git-config .git/config &&
704 cp pristine-.gitmodules .gitmodules &&
705 git config remote.origin.url foo &&
706 # actual: fails with an error
707 git submodule init &&
708 test "$(git config submodule.sub.url)" = subrepo
709 )
710'
711
712test_expect_success '../subrepo works with relative local path - foo/bar' '
713 (
714 cd reltest &&
715 cp pristine-.git-config .git/config &&
716 cp pristine-.gitmodules .gitmodules &&
717 git config remote.origin.url foo/bar &&
718 git submodule init &&
719 test "$(git config submodule.sub.url)" = foo/subrepo
720 )
721'
722
723test_expect_success '../subrepo works with relative local path - ./foo' '
724 (
725 cd reltest &&
726 cp pristine-.git-config .git/config &&
727 cp pristine-.gitmodules .gitmodules &&
728 git config remote.origin.url ./foo &&
729 git submodule init &&
730 test "$(git config submodule.sub.url)" = subrepo
731 )
732'
733
734test_expect_success '../subrepo works with relative local path - ./foo/bar' '
735 (
736 cd reltest &&
737 cp pristine-.git-config .git/config &&
738 cp pristine-.gitmodules .gitmodules &&
739 git config remote.origin.url ./foo/bar &&
740 git submodule init &&
741 test "$(git config submodule.sub.url)" = foo/subrepo
742 )
743'
744
745test_expect_success '../subrepo works with relative local path - ../foo' '
746 (
747 cd reltest &&
748 cp pristine-.git-config .git/config &&
749 cp pristine-.gitmodules .gitmodules &&
750 git config remote.origin.url ../foo &&
751 git submodule init &&
752 test "$(git config submodule.sub.url)" = ../subrepo
753 )
754'
755
756test_expect_success '../subrepo works with relative local path - ../foo/bar' '
757 (
758 cd reltest &&
759 cp pristine-.git-config .git/config &&
760 cp pristine-.gitmodules .gitmodules &&
761 git config remote.origin.url ../foo/bar &&
762 git submodule init &&
763 test "$(git config submodule.sub.url)" = ../foo/subrepo
764 )
765'
766
767test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
768 (
769 cd reltest &&
770 cp pristine-.git-config .git/config &&
771 cp pristine-.gitmodules .gitmodules &&
772 mkdir -p a/b/c &&
773 (cd a/b/c; git init) &&
774 git config remote.origin.url ../foo/bar.git &&
775 git submodule add ../bar/a/b/c ./a/b/c &&
776 git submodule init &&
777 test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
778 )
779'
780
781test_expect_success 'moving the superproject does not break submodules' '
782 (
783 cd addtest &&
784 git submodule status >expect
785 ) &&
786 mv addtest addtest2 &&
787 (
788 cd addtest2 &&
789 git submodule status >actual &&
790 test_cmp expect actual
791 )
792'
793
794test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
795 (
796 cd addtest2 &&
797 (
798 cd repo &&
799 echo "$submodurl/repo" >expect &&
800 git config remote.origin.url >actual &&
801 test_cmp expect actual &&
802 echo "gitdir: ../.git/modules/repo" >expect &&
803 test_cmp expect .git
804 ) &&
805 rm -rf repo &&
806 git rm repo &&
807 git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
808 test_must_be_empty actual &&
809 echo "gitdir: ../.git/modules/submod" >expect &&
810 test_cmp expect submod/.git &&
811 (
812 cd repo &&
813 echo "$submodurl/bare.git" >expect &&
814 git config remote.origin.url >actual &&
815 test_cmp expect actual &&
816 echo "gitdir: ../.git/modules/repo_new" >expect &&
817 test_cmp expect .git
818 ) &&
819 echo "repo" >expect &&
820 test_must_fail git config -f .gitmodules submodule.repo.path &&
821 git config -f .gitmodules submodule.repo_new.path >actual &&
822 test_cmp expect actual&&
823 echo "$submodurl/repo" >expect &&
824 test_must_fail git config -f .gitmodules submodule.repo.url &&
825 echo "$submodurl/bare.git" >expect &&
826 git config -f .gitmodules submodule.repo_new.url >actual &&
827 test_cmp expect actual &&
828 echo "$submodurl/repo" >expect &&
829 git config submodule.repo.url >actual &&
830 test_cmp expect actual &&
831 echo "$submodurl/bare.git" >expect &&
832 git config submodule.repo_new.url >actual &&
833 test_cmp expect actual
834 )
835'
836
837test_expect_success 'recursive relative submodules stay relative' '
838 test_when_finished "rm -rf super clone2 subsub sub3" &&
839 mkdir subsub &&
840 (
841 cd subsub &&
842 git init &&
843 >t &&
844 git add t &&
845 git commit -m "initial commit"
846 ) &&
847 mkdir sub3 &&
848 (
849 cd sub3 &&
850 git init &&
851 >t &&
852 git add t &&
853 git commit -m "initial commit" &&
854 git submodule add ../subsub dirdir/subsub &&
855 git commit -m "add submodule subsub"
856 ) &&
857 mkdir super &&
858 (
859 cd super &&
860 git init &&
861 >t &&
862 git add t &&
863 git commit -m "initial commit" &&
864 git submodule add ../sub3 &&
865 git commit -m "add submodule sub"
866 ) &&
867 git clone super clone2 &&
868 (
869 cd clone2 &&
870 git submodule update --init --recursive &&
871 echo "gitdir: ../.git/modules/sub3" >./sub3/.git_expect &&
872 echo "gitdir: ../../../.git/modules/sub3/modules/dirdir/subsub" >./sub3/dirdir/subsub/.git_expect
873 ) &&
874 test_cmp clone2/sub3/.git_expect clone2/sub3/.git &&
875 test_cmp clone2/sub3/dirdir/subsub/.git_expect clone2/sub3/dirdir/subsub/.git
876'
877
878test_expect_success 'submodule add with an existing name fails unless forced' '
879 (
880 cd addtest2 &&
881 rm -rf repo &&
882 git rm repo &&
883 test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
884 test ! -d repo &&
885 test_must_fail git config -f .gitmodules submodule.repo_new.path &&
886 test_must_fail git config -f .gitmodules submodule.repo_new.url &&
887 echo "$submodurl/bare.git" >expect &&
888 git config submodule.repo_new.url >actual &&
889 test_cmp expect actual &&
890 git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
891 test -d repo &&
892 echo "repo" >expect &&
893 git config -f .gitmodules submodule.repo_new.path >actual &&
894 test_cmp expect actual&&
895 echo "$submodurl/repo.git" >expect &&
896 git config -f .gitmodules submodule.repo_new.url >actual &&
897 test_cmp expect actual &&
898 echo "$submodurl/repo.git" >expect &&
899 git config submodule.repo_new.url >actual &&
900 test_cmp expect actual
901 )
902'
903
904test_expect_success 'set up a second submodule' '
905 git submodule add ./init2 example2 &&
906 git commit -m "submodule example2 added"
907'
908
909test_expect_success 'submodule deinit works on repository without submodules' '
910 test_when_finished "rm -rf newdirectory" &&
911 mkdir newdirectory &&
912 (
913 cd newdirectory &&
914 git init &&
915 >file &&
916 git add file &&
917 git commit -m "repo should not be empty"
918 git submodule deinit .
919 )
920'
921
922test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
923 git config submodule.example.foo bar &&
924 git config submodule.example2.frotz nitfol &&
925 git submodule deinit init &&
926 test -z "$(git config --get-regexp "submodule\.example\.")" &&
927 test -n "$(git config --get-regexp "submodule\.example2\.")" &&
928 test -f example2/.git &&
929 rmdir init
930'
931
932test_expect_success 'submodule deinit from subdirectory' '
933 git submodule update --init &&
934 git config submodule.example.foo bar &&
935 mkdir -p sub &&
936 (
937 cd sub &&
938 git submodule deinit ../init >../output
939 ) &&
940 grep "\\.\\./init" output &&
941 test -z "$(git config --get-regexp "submodule\.example\.")" &&
942 test -n "$(git config --get-regexp "submodule\.example2\.")" &&
943 test -f example2/.git &&
944 rmdir init
945'
946
947test_expect_success 'submodule deinit . deinits all initialized submodules' '
948 git submodule update --init &&
949 git config submodule.example.foo bar &&
950 git config submodule.example2.frotz nitfol &&
951 test_must_fail git submodule deinit &&
952 git submodule deinit . >actual &&
953 test -z "$(git config --get-regexp "submodule\.example\.")" &&
954 test -z "$(git config --get-regexp "submodule\.example2\.")" &&
955 test_i18ngrep "Cleared directory .init" actual &&
956 test_i18ngrep "Cleared directory .example2" actual &&
957 rmdir init example2
958'
959
960test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' '
961 git submodule update --init &&
962 rm -rf init example2/* example2/.git &&
963 git submodule deinit init example2 >actual &&
964 test -z "$(git config --get-regexp "submodule\.example\.")" &&
965 test -z "$(git config --get-regexp "submodule\.example2\.")" &&
966 test_i18ngrep ! "Cleared directory .init" actual &&
967 test_i18ngrep "Cleared directory .example2" actual &&
968 rmdir init
969'
970
971test_expect_success 'submodule deinit fails when the submodule contains modifications unless forced' '
972 git submodule update --init &&
973 echo X >>init/s &&
974 test_must_fail git submodule deinit init &&
975 test -n "$(git config --get-regexp "submodule\.example\.")" &&
976 test -f example2/.git &&
977 git submodule deinit -f init >actual &&
978 test -z "$(git config --get-regexp "submodule\.example\.")" &&
979 test_i18ngrep "Cleared directory .init" actual &&
980 rmdir init
981'
982
983test_expect_success 'submodule deinit fails when the submodule contains untracked files unless forced' '
984 git submodule update --init &&
985 echo X >>init/untracked &&
986 test_must_fail git submodule deinit init &&
987 test -n "$(git config --get-regexp "submodule\.example\.")" &&
988 test -f example2/.git &&
989 git submodule deinit -f init >actual &&
990 test -z "$(git config --get-regexp "submodule\.example\.")" &&
991 test_i18ngrep "Cleared directory .init" actual &&
992 rmdir init
993'
994
995test_expect_success 'submodule deinit fails when the submodule HEAD does not match unless forced' '
996 git submodule update --init &&
997 (
998 cd init &&
999 git checkout HEAD^
1000 ) &&
1001 test_must_fail git submodule deinit init &&
1002 test -n "$(git config --get-regexp "submodule\.example\.")" &&
1003 test -f example2/.git &&
1004 git submodule deinit -f init >actual &&
1005 test -z "$(git config --get-regexp "submodule\.example\.")" &&
1006 test_i18ngrep "Cleared directory .init" actual &&
1007 rmdir init
1008'
1009
1010test_expect_success 'submodule deinit is silent when used on an uninitialized submodule' '
1011 git submodule update --init &&
1012 git submodule deinit init >actual &&
1013 test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual &&
1014 test_i18ngrep "Cleared directory .init" actual &&
1015 git submodule deinit init >actual &&
1016 test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
1017 test_i18ngrep "Cleared directory .init" actual &&
1018 git submodule deinit . >actual &&
1019 test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
1020 test_i18ngrep "Submodule .example2. (.*) unregistered for path .example2" actual &&
1021 test_i18ngrep "Cleared directory .init" actual &&
1022 git submodule deinit . >actual &&
1023 test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
1024 test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
1025 test_i18ngrep "Cleared directory .init" actual &&
1026 rmdir init example2
1027'
1028
1029test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' '
1030 git submodule update --init &&
1031 (
1032 cd init &&
1033 rm .git &&
1034 cp -R ../.git/modules/example .git &&
1035 GIT_WORK_TREE=. git config --unset core.worktree
1036 ) &&
1037 test_must_fail git submodule deinit init &&
1038 test_must_fail git submodule deinit -f init &&
1039 test -d init/.git &&
1040 test -n "$(git config --get-regexp "submodule\.example\.")"
1041'
1042
1043test_expect_success 'submodule with UTF-8 name' '
1044 svname=$(printf "\303\245 \303\244\303\266") &&
1045 mkdir "$svname" &&
1046 (
1047 cd "$svname" &&
1048 git init &&
1049 >sub &&
1050 git add sub &&
1051 git commit -m "init sub"
1052 ) &&
1053 git submodule add ./"$svname" &&
1054 git submodule >&2 &&
1055 test -n "$(git submodule | grep "$svname")"
1056'
1057
1058test_expect_success 'submodule add clone shallow submodule' '
1059 mkdir super &&
1060 pwd=$(pwd) &&
1061 (
1062 cd super &&
1063 git init &&
1064 git submodule add --depth=1 file://"$pwd"/example2 submodule &&
1065 (
1066 cd submodule &&
1067 test 1 = $(git log --oneline | wc -l)
1068 )
1069 )
1070'
1071
1072test_expect_success 'submodule helper list is not confused by common prefixes' '
1073 mkdir -p dir1/b &&
1074 (
1075 cd dir1/b &&
1076 git init &&
1077 echo hi >testfile2 &&
1078 git add . &&
1079 git commit -m "test1"
1080 ) &&
1081 mkdir -p dir2/b &&
1082 (
1083 cd dir2/b &&
1084 git init &&
1085 echo hello >testfile1 &&
1086 git add . &&
1087 git commit -m "test2"
1088 ) &&
1089 git submodule add /dir1/b dir1/b &&
1090 git submodule add /dir2/b dir2/b &&
1091 git commit -m "first submodule commit" &&
1092 git submodule--helper list dir1/b |cut -c51- >actual &&
1093 echo "dir1/b" >expect &&
1094 test_cmp expect actual
1095'
1096
1097
1098test_done