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