Merge branch 'rs/strbuf-getcwd'
[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 --file=.gitmodules submodule.example.url git://example.com/init.git
253 '
254
255 test_expect_success 'status should fail for unmapped paths' '
256         test_must_fail git submodule status
257 '
258
259 test_expect_success 'setup - map path in .gitmodules' '
260         cat <<\EOF >expect &&
261 [submodule "example"]
262         url = git://example.com/init.git
263         path = init
264 EOF
265
266         git config --file=.gitmodules submodule.example.path init &&
267
268         test_cmp expect .gitmodules
269 '
270
271 test_expect_success 'status should only print one line' '
272         git submodule status >lines &&
273         test_line_count = 1 lines
274 '
275
276 test_expect_success 'setup - fetch commit name from submodule' '
277         rev1=$(cd .subrepo && git rev-parse HEAD) &&
278         printf "rev1: %s\n" "$rev1" &&
279         test -n "$rev1"
280 '
281
282 test_expect_success 'status should initially be "missing"' '
283         git submodule status >lines &&
284         grep "^-$rev1" lines
285 '
286
287 test_expect_success 'init should register submodule url in .git/config' '
288         echo git://example.com/init.git >expect &&
289
290         git submodule init &&
291         git config submodule.example.url >url &&
292         git config submodule.example.url ./.subrepo &&
293
294         test_cmp expect url
295 '
296
297 test_failure_with_unknown_submodule () {
298         test_must_fail git submodule $1 no-such-submodule 2>output.err &&
299         grep "^error: .*no-such-submodule" output.err
300 }
301
302 test_expect_success 'init should fail with unknown submodule' '
303         test_failure_with_unknown_submodule init
304 '
305
306 test_expect_success 'update should fail with unknown submodule' '
307         test_failure_with_unknown_submodule update
308 '
309
310 test_expect_success 'status should fail with unknown submodule' '
311         test_failure_with_unknown_submodule status
312 '
313
314 test_expect_success 'sync should fail with unknown submodule' '
315         test_failure_with_unknown_submodule sync
316 '
317
318 test_expect_success 'update should fail when path is used by a file' '
319         echo hello >expect &&
320
321         echo "hello" >init &&
322         test_must_fail git submodule update &&
323
324         test_cmp expect init
325 '
326
327 test_expect_success 'update should fail when path is used by a nonempty directory' '
328         echo hello >expect &&
329
330         rm -fr init &&
331         mkdir init &&
332         echo "hello" >init/a &&
333
334         test_must_fail git submodule update &&
335
336         test_cmp expect init/a
337 '
338
339 test_expect_success 'update should work when path is an empty dir' '
340         rm -fr init &&
341         rm -f head-sha1 &&
342         echo "$rev1" >expect &&
343
344         mkdir init &&
345         git submodule update -q >update.out &&
346         test_must_be_empty update.out &&
347
348         inspect init &&
349         test_cmp expect head-sha1
350 '
351
352 test_expect_success 'status should be "up-to-date" after update' '
353         git submodule status >list &&
354         grep "^ $rev1" list
355 '
356
357 test_expect_success 'status "up-to-date" from subdirectory' '
358         mkdir -p sub &&
359         (
360                 cd sub &&
361                 git submodule status >../list
362         ) &&
363         grep "^ $rev1" list &&
364         grep "\\.\\./init" list
365 '
366
367 test_expect_success 'status "up-to-date" from subdirectory with path' '
368         mkdir -p sub &&
369         (
370                 cd sub &&
371                 git submodule status ../init >../list
372         ) &&
373         grep "^ $rev1" list &&
374         grep "\\.\\./init" list
375 '
376
377 test_expect_success 'status should be "modified" after submodule commit' '
378         (
379                 cd init &&
380                 echo b >b &&
381                 git add b &&
382                 git commit -m "submodule commit 2"
383         ) &&
384
385         rev2=$(cd init && git rev-parse HEAD) &&
386         test -n "$rev2" &&
387         git submodule status >list &&
388
389         grep "^+$rev2" list
390 '
391
392 test_expect_success 'the --cached sha1 should be rev1' '
393         git submodule --cached status >list &&
394         grep "^+$rev1" list
395 '
396
397 test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
398         git diff >diff &&
399         grep "^+Subproject commit $rev2" diff
400 '
401
402 test_expect_success 'update should checkout rev1' '
403         rm -f head-sha1 &&
404         echo "$rev1" >expect &&
405
406         git submodule update init &&
407         inspect init &&
408
409         test_cmp expect head-sha1
410 '
411
412 test_expect_success 'status should be "up-to-date" after update' '
413         git submodule status >list &&
414         grep "^ $rev1" list
415 '
416
417 test_expect_success 'checkout superproject with subproject already present' '
418         git checkout initial &&
419         git checkout master
420 '
421
422 test_expect_success 'apply submodule diff' '
423         >empty &&
424
425         git branch second &&
426         (
427                 cd init &&
428                 echo s >s &&
429                 git add s &&
430                 git commit -m "change subproject"
431         ) &&
432         git update-index --add init &&
433         git commit -m "change init" &&
434         git format-patch -1 --stdout >P.diff &&
435         git checkout second &&
436         git apply --index P.diff &&
437
438         git diff --cached master >staged &&
439         test_cmp empty staged
440 '
441
442 test_expect_success 'update --init' '
443         mv init init2 &&
444         git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
445         git config --remove-section submodule.example &&
446         test_must_fail git config submodule.example.url &&
447
448         git submodule update init > update.out &&
449         cat update.out &&
450         test_i18ngrep "not initialized" update.out &&
451         test_must_fail git rev-parse --resolve-git-dir init/.git &&
452
453         git submodule update --init init &&
454         git rev-parse --resolve-git-dir init/.git
455 '
456
457 test_expect_success 'update --init from subdirectory' '
458         mv init init2 &&
459         git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
460         git config --remove-section submodule.example &&
461         test_must_fail git config submodule.example.url &&
462
463         mkdir -p sub &&
464         (
465                 cd sub &&
466                 git submodule update ../init >update.out &&
467                 cat update.out &&
468                 test_i18ngrep "not initialized" update.out &&
469                 test_must_fail git rev-parse --resolve-git-dir ../init/.git &&
470
471                 git submodule update --init ../init
472         ) &&
473         git rev-parse --resolve-git-dir init/.git
474 '
475
476 test_expect_success 'do not add files from a submodule' '
477
478         git reset --hard &&
479         test_must_fail git add init/a
480
481 '
482
483 test_expect_success 'gracefully add/reset submodule with a trailing slash' '
484
485         git reset --hard &&
486         git commit -m "commit subproject" init &&
487         (cd init &&
488          echo b > a) &&
489         git add init/ &&
490         git diff --exit-code --cached init &&
491         commit=$(cd init &&
492          git commit -m update a >/dev/null &&
493          git rev-parse HEAD) &&
494         git add init/ &&
495         test_must_fail git diff --exit-code --cached init &&
496         test $commit = $(git ls-files --stage |
497                 sed -n "s/^160000 \([^ ]*\).*/\1/p") &&
498         git reset init/ &&
499         git diff --exit-code --cached init
500
501 '
502
503 test_expect_success 'ls-files gracefully handles trailing slash' '
504
505         test "init" = "$(git ls-files init/)"
506
507 '
508
509 test_expect_success 'moving to a commit without submodule does not leave empty dir' '
510         rm -rf init &&
511         mkdir init &&
512         git reset --hard &&
513         git checkout initial &&
514         test ! -d init &&
515         git checkout second
516 '
517
518 test_expect_success 'submodule <invalid-subcommand> fails' '
519         test_must_fail git submodule no-such-subcommand
520 '
521
522 test_expect_success 'add submodules without specifying an explicit path' '
523         mkdir repo &&
524         (
525                 cd repo &&
526                 git init &&
527                 echo r >r &&
528                 git add r &&
529                 git commit -m "repo commit 1"
530         ) &&
531         git clone --bare repo/ bare.git &&
532         (
533                 cd addtest &&
534                 git submodule add "$submodurl/repo" &&
535                 git config -f .gitmodules submodule.repo.path repo &&
536                 git submodule add "$submodurl/bare.git" &&
537                 git config -f .gitmodules submodule.bare.path bare
538         )
539 '
540
541 test_expect_success 'add should fail when path is used by a file' '
542         (
543                 cd addtest &&
544                 touch file &&
545                 test_must_fail  git submodule add "$submodurl/repo" file
546         )
547 '
548
549 test_expect_success 'add should fail when path is used by an existing directory' '
550         (
551                 cd addtest &&
552                 mkdir empty-dir &&
553                 test_must_fail git submodule add "$submodurl/repo" empty-dir
554         )
555 '
556
557 test_expect_success 'use superproject as upstream when path is relative and no url is set there' '
558         (
559                 cd addtest &&
560                 git submodule add ../repo relative &&
561                 test "$(git config -f .gitmodules submodule.relative.url)" = ../repo &&
562                 git submodule sync relative &&
563                 test "$(git config submodule.relative.url)" = "$submodurl/repo"
564         )
565 '
566
567 test_expect_success 'set up for relative path tests' '
568         mkdir reltest &&
569         (
570                 cd reltest &&
571                 git init &&
572                 mkdir sub &&
573                 (
574                         cd sub &&
575                         git init &&
576                         test_commit foo
577                 ) &&
578                 git add sub &&
579                 git config -f .gitmodules submodule.sub.path sub &&
580                 git config -f .gitmodules submodule.sub.url ../subrepo &&
581                 cp .git/config pristine-.git-config &&
582                 cp .gitmodules pristine-.gitmodules
583         )
584 '
585
586 test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
587         (
588                 cd reltest &&
589                 cp pristine-.git-config .git/config &&
590                 cp pristine-.gitmodules .gitmodules &&
591                 git config remote.origin.url ssh://hostname/repo &&
592                 git submodule init &&
593                 test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
594         )
595 '
596
597 test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
598         (
599                 cd reltest &&
600                 cp pristine-.git-config .git/config &&
601                 cp pristine-.gitmodules .gitmodules &&
602                 git config remote.origin.url ssh://hostname:22/repo &&
603                 git submodule init &&
604                 test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
605         )
606 '
607
608 # About the choice of the path in the next test:
609 # - double-slash side-steps path mangling issues on Windows
610 # - it is still an absolute local path
611 # - there cannot be a server with a blank in its name just in case the
612 #   path is used erroneously to access a //server/share style path
613 test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
614         (
615                 cd reltest &&
616                 cp pristine-.git-config .git/config &&
617                 cp pristine-.gitmodules .gitmodules &&
618                 git config remote.origin.url "//somewhere else/repo" &&
619                 git submodule init &&
620                 test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
621         )
622 '
623
624 test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
625         (
626                 cd reltest &&
627                 cp pristine-.git-config .git/config &&
628                 cp pristine-.gitmodules .gitmodules &&
629                 git config remote.origin.url file:///tmp/repo &&
630                 git submodule init &&
631                 test "$(git config submodule.sub.url)" = file:///tmp/subrepo
632         )
633 '
634
635 test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
636         (
637                 cd reltest &&
638                 cp pristine-.git-config .git/config &&
639                 cp pristine-.gitmodules .gitmodules &&
640                 git config remote.origin.url helper:://hostname/repo &&
641                 git submodule init &&
642                 test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
643         )
644 '
645
646 test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
647         (
648                 cd reltest &&
649                 cp pristine-.git-config .git/config &&
650                 git config remote.origin.url user@host:repo &&
651                 git submodule init &&
652                 test "$(git config submodule.sub.url)" = user@host:subrepo
653         )
654 '
655
656 test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
657         (
658                 cd reltest &&
659                 cp pristine-.git-config .git/config &&
660                 cp pristine-.gitmodules .gitmodules &&
661                 git config remote.origin.url user@host:path/to/repo &&
662                 git submodule init &&
663                 test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
664         )
665 '
666
667 test_expect_success '../subrepo works with relative local path - foo' '
668         (
669                 cd reltest &&
670                 cp pristine-.git-config .git/config &&
671                 cp pristine-.gitmodules .gitmodules &&
672                 git config remote.origin.url foo &&
673                 # actual: fails with an error
674                 git submodule init &&
675                 test "$(git config submodule.sub.url)" = subrepo
676         )
677 '
678
679 test_expect_success '../subrepo works with relative local path - foo/bar' '
680         (
681                 cd reltest &&
682                 cp pristine-.git-config .git/config &&
683                 cp pristine-.gitmodules .gitmodules &&
684                 git config remote.origin.url foo/bar &&
685                 git submodule init &&
686                 test "$(git config submodule.sub.url)" = foo/subrepo
687         )
688 '
689
690 test_expect_success '../subrepo works with relative local path - ./foo' '
691         (
692                 cd reltest &&
693                 cp pristine-.git-config .git/config &&
694                 cp pristine-.gitmodules .gitmodules &&
695                 git config remote.origin.url ./foo &&
696                 git submodule init &&
697                 test "$(git config submodule.sub.url)" = subrepo
698         )
699 '
700
701 test_expect_success '../subrepo works with relative local path - ./foo/bar' '
702         (
703                 cd reltest &&
704                 cp pristine-.git-config .git/config &&
705                 cp pristine-.gitmodules .gitmodules &&
706                 git config remote.origin.url ./foo/bar &&
707                 git submodule init &&
708                 test "$(git config submodule.sub.url)" = foo/subrepo
709         )
710 '
711
712 test_expect_success '../subrepo works with relative local path - ../foo' '
713         (
714                 cd reltest &&
715                 cp pristine-.git-config .git/config &&
716                 cp pristine-.gitmodules .gitmodules &&
717                 git config remote.origin.url ../foo &&
718                 git submodule init &&
719                 test "$(git config submodule.sub.url)" = ../subrepo
720         )
721 '
722
723 test_expect_success '../subrepo works with relative local path - ../foo/bar' '
724         (
725                 cd reltest &&
726                 cp pristine-.git-config .git/config &&
727                 cp pristine-.gitmodules .gitmodules &&
728                 git config remote.origin.url ../foo/bar &&
729                 git submodule init &&
730                 test "$(git config submodule.sub.url)" = ../foo/subrepo
731         )
732 '
733
734 test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
735         (
736                 cd reltest &&
737                 cp pristine-.git-config .git/config &&
738                 cp pristine-.gitmodules .gitmodules &&
739                 mkdir -p a/b/c &&
740                 (cd a/b/c; git init) &&
741                 git config remote.origin.url ../foo/bar.git &&
742                 git submodule add ../bar/a/b/c ./a/b/c &&
743                 git submodule init &&
744                 test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
745         )
746 '
747
748 test_expect_success 'moving the superproject does not break submodules' '
749         (
750                 cd addtest &&
751                 git submodule status >expect
752         )
753         mv addtest addtest2 &&
754         (
755                 cd addtest2 &&
756                 git submodule status >actual &&
757                 test_cmp expect actual
758         )
759 '
760
761 test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
762         (
763                 cd addtest2 &&
764                 (
765                         cd repo &&
766                         echo "$submodurl/repo" >expect &&
767                         git config remote.origin.url >actual &&
768                         test_cmp expect actual &&
769                         echo "gitdir: ../.git/modules/repo" >expect &&
770                         test_cmp expect .git
771                 ) &&
772                 rm -rf repo &&
773                 git rm repo &&
774                 git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
775                 test_must_be_empty actual &&
776                 echo "gitdir: ../.git/modules/submod" >expect &&
777                 test_cmp expect submod/.git &&
778                 (
779                         cd repo &&
780                         echo "$submodurl/bare.git" >expect &&
781                         git config remote.origin.url >actual &&
782                         test_cmp expect actual &&
783                         echo "gitdir: ../.git/modules/repo_new" >expect &&
784                         test_cmp expect .git
785                 ) &&
786                 echo "repo" >expect &&
787                 test_must_fail git config -f .gitmodules submodule.repo.path &&
788                 git config -f .gitmodules submodule.repo_new.path >actual &&
789                 test_cmp expect actual&&
790                 echo "$submodurl/repo" >expect &&
791                 test_must_fail git config -f .gitmodules submodule.repo.url &&
792                 echo "$submodurl/bare.git" >expect &&
793                 git config -f .gitmodules submodule.repo_new.url >actual &&
794                 test_cmp expect actual &&
795                 echo "$submodurl/repo" >expect &&
796                 git config submodule.repo.url >actual &&
797                 test_cmp expect actual &&
798                 echo "$submodurl/bare.git" >expect &&
799                 git config submodule.repo_new.url >actual &&
800                 test_cmp expect actual
801         )
802 '
803
804 test_expect_success 'submodule add with an existing name fails unless forced' '
805         (
806                 cd addtest2 &&
807                 rm -rf repo &&
808                 git rm repo &&
809                 test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
810                 test ! -d repo &&
811                 test_must_fail git config -f .gitmodules submodule.repo_new.path &&
812                 test_must_fail git config -f .gitmodules submodule.repo_new.url &&
813                 echo "$submodurl/bare.git" >expect &&
814                 git config submodule.repo_new.url >actual &&
815                 test_cmp expect actual &&
816                 git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
817                 test -d repo &&
818                 echo "repo" >expect &&
819                 git config -f .gitmodules submodule.repo_new.path >actual &&
820                 test_cmp expect actual&&
821                 echo "$submodurl/repo.git" >expect &&
822                 git config -f .gitmodules submodule.repo_new.url >actual &&
823                 test_cmp expect actual &&
824                 echo "$submodurl/repo.git" >expect &&
825                 git config submodule.repo_new.url >actual &&
826                 test_cmp expect actual
827         )
828 '
829
830 test_expect_success 'set up a second submodule' '
831         git submodule add ./init2 example2 &&
832         git commit -m "submodule example2 added"
833 '
834
835 test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
836         git config submodule.example.foo bar &&
837         git config submodule.example2.frotz nitfol &&
838         git submodule deinit init &&
839         test -z "$(git config --get-regexp "submodule\.example\.")" &&
840         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
841         test -f example2/.git &&
842         rmdir init
843 '
844
845 test_expect_success 'submodule deinit from subdirectory' '
846         git submodule update --init &&
847         git config submodule.example.foo bar &&
848         mkdir -p sub &&
849         (
850                 cd sub &&
851                 git submodule deinit ../init >../output
852         ) &&
853         grep "\\.\\./init" output &&
854         test -z "$(git config --get-regexp "submodule\.example\.")" &&
855         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
856         test -f example2/.git &&
857         rmdir init
858 '
859
860 test_expect_success 'submodule deinit . deinits all initialized submodules' '
861         git submodule update --init &&
862         git config submodule.example.foo bar &&
863         git config submodule.example2.frotz nitfol &&
864         test_must_fail git submodule deinit &&
865         git submodule deinit . >actual &&
866         test -z "$(git config --get-regexp "submodule\.example\.")" &&
867         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
868         test_i18ngrep "Cleared directory .init" actual &&
869         test_i18ngrep "Cleared directory .example2" actual &&
870         rmdir init example2
871 '
872
873 test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' '
874         git submodule update --init &&
875         rm -rf init example2/* example2/.git &&
876         git submodule deinit init example2 >actual &&
877         test -z "$(git config --get-regexp "submodule\.example\.")" &&
878         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
879         test_i18ngrep ! "Cleared directory .init" actual &&
880         test_i18ngrep "Cleared directory .example2" actual &&
881         rmdir init
882 '
883
884 test_expect_success 'submodule deinit fails when the submodule contains modifications unless forced' '
885         git submodule update --init &&
886         echo X >>init/s &&
887         test_must_fail git submodule deinit init &&
888         test -n "$(git config --get-regexp "submodule\.example\.")" &&
889         test -f example2/.git &&
890         git submodule deinit -f init >actual &&
891         test -z "$(git config --get-regexp "submodule\.example\.")" &&
892         test_i18ngrep "Cleared directory .init" actual &&
893         rmdir init
894 '
895
896 test_expect_success 'submodule deinit fails when the submodule contains untracked files unless forced' '
897         git submodule update --init &&
898         echo X >>init/untracked &&
899         test_must_fail git submodule deinit init &&
900         test -n "$(git config --get-regexp "submodule\.example\.")" &&
901         test -f example2/.git &&
902         git submodule deinit -f init >actual &&
903         test -z "$(git config --get-regexp "submodule\.example\.")" &&
904         test_i18ngrep "Cleared directory .init" actual &&
905         rmdir init
906 '
907
908 test_expect_success 'submodule deinit fails when the submodule HEAD does not match unless forced' '
909         git submodule update --init &&
910         (
911                 cd init &&
912                 git checkout HEAD^
913         ) &&
914         test_must_fail git submodule deinit init &&
915         test -n "$(git config --get-regexp "submodule\.example\.")" &&
916         test -f example2/.git &&
917         git submodule deinit -f init >actual &&
918         test -z "$(git config --get-regexp "submodule\.example\.")" &&
919         test_i18ngrep "Cleared directory .init" actual &&
920         rmdir init
921 '
922
923 test_expect_success 'submodule deinit is silent when used on an uninitialized submodule' '
924         git submodule update --init &&
925         git submodule deinit init >actual &&
926         test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual &&
927         test_i18ngrep "Cleared directory .init" actual &&
928         git submodule deinit init >actual &&
929         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
930         test_i18ngrep "Cleared directory .init" actual &&
931         git submodule deinit . >actual &&
932         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
933         test_i18ngrep "Submodule .example2. (.*) unregistered for path .example2" actual &&
934         test_i18ngrep "Cleared directory .init" actual &&
935         git submodule deinit . >actual &&
936         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
937         test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
938         test_i18ngrep "Cleared directory .init" actual &&
939         rmdir init example2
940 '
941
942 test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' '
943         git submodule update --init &&
944         (
945                 cd init &&
946                 rm .git &&
947                 cp -R ../.git/modules/example .git &&
948                 GIT_WORK_TREE=. git config --unset core.worktree
949         ) &&
950         test_must_fail git submodule deinit init &&
951         test_must_fail git submodule deinit -f init &&
952         test -d init/.git &&
953         test -n "$(git config --get-regexp "submodule\.example\.")"
954 '
955
956 test_expect_success 'submodule with UTF-8 name' '
957         svname=$(printf "\303\245 \303\244\303\266") &&
958         mkdir "$svname" &&
959         (
960                 cd "$svname" &&
961                 git init &&
962                 >sub &&
963                 git add sub &&
964                 git commit -m "init sub"
965         ) &&
966         git submodule add ./"$svname" &&
967         git submodule >&2 &&
968         test -n "$(git submodule | grep "$svname")"
969 '
970
971 test_expect_success 'submodule add clone shallow submodule' '
972         mkdir super &&
973         pwd=$(pwd)
974         (
975                 cd super &&
976                 git init &&
977                 git submodule add --depth=1 file://"$pwd"/example2 submodule &&
978                 (
979                         cd submodule &&
980                         test 1 = $(git log --oneline | wc -l)
981                 )
982         )
983 '
984
985
986 test_done