Merge branch 'sh/pull-rebase-preserve'
[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 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
500 '
501
502 test_expect_success 'ls-files gracefully handles trailing slash' '
503
504         test "init" = "$(git ls-files init/)"
505
506 '
507
508 test_expect_success 'moving to a commit without submodule does not leave empty dir' '
509         rm -rf init &&
510         mkdir init &&
511         git reset --hard &&
512         git checkout initial &&
513         test ! -d init &&
514         git checkout second
515 '
516
517 test_expect_success 'submodule <invalid-subcommand> fails' '
518         test_must_fail git submodule no-such-subcommand
519 '
520
521 test_expect_success 'add submodules without specifying an explicit path' '
522         mkdir repo &&
523         (
524                 cd repo &&
525                 git init &&
526                 echo r >r &&
527                 git add r &&
528                 git commit -m "repo commit 1"
529         ) &&
530         git clone --bare repo/ bare.git &&
531         (
532                 cd addtest &&
533                 git submodule add "$submodurl/repo" &&
534                 git config -f .gitmodules submodule.repo.path repo &&
535                 git submodule add "$submodurl/bare.git" &&
536                 git config -f .gitmodules submodule.bare.path bare
537         )
538 '
539
540 test_expect_success 'add should fail when path is used by a file' '
541         (
542                 cd addtest &&
543                 touch file &&
544                 test_must_fail  git submodule add "$submodurl/repo" file
545         )
546 '
547
548 test_expect_success 'add should fail when path is used by an existing directory' '
549         (
550                 cd addtest &&
551                 mkdir empty-dir &&
552                 test_must_fail git submodule add "$submodurl/repo" empty-dir
553         )
554 '
555
556 test_expect_success 'use superproject as upstream when path is relative and no url is set there' '
557         (
558                 cd addtest &&
559                 git submodule add ../repo relative &&
560                 test "$(git config -f .gitmodules submodule.relative.url)" = ../repo &&
561                 git submodule sync relative &&
562                 test "$(git config submodule.relative.url)" = "$submodurl/repo"
563         )
564 '
565
566 test_expect_success 'set up for relative path tests' '
567         mkdir reltest &&
568         (
569                 cd reltest &&
570                 git init &&
571                 mkdir sub &&
572                 (
573                         cd sub &&
574                         git init &&
575                         test_commit foo
576                 ) &&
577                 git add sub &&
578                 git config -f .gitmodules submodule.sub.path sub &&
579                 git config -f .gitmodules submodule.sub.url ../subrepo &&
580                 cp .git/config pristine-.git-config &&
581                 cp .gitmodules pristine-.gitmodules
582         )
583 '
584
585 test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
586         (
587                 cd reltest &&
588                 cp pristine-.git-config .git/config &&
589                 cp pristine-.gitmodules .gitmodules &&
590                 git config remote.origin.url ssh://hostname/repo &&
591                 git submodule init &&
592                 test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
593         )
594 '
595
596 test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
597         (
598                 cd reltest &&
599                 cp pristine-.git-config .git/config &&
600                 cp pristine-.gitmodules .gitmodules &&
601                 git config remote.origin.url ssh://hostname:22/repo &&
602                 git submodule init &&
603                 test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
604         )
605 '
606
607 # About the choice of the path in the next test:
608 # - double-slash side-steps path mangling issues on Windows
609 # - it is still an absolute local path
610 # - there cannot be a server with a blank in its name just in case the
611 #   path is used erroneously to access a //server/share style path
612 test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
613         (
614                 cd reltest &&
615                 cp pristine-.git-config .git/config &&
616                 cp pristine-.gitmodules .gitmodules &&
617                 git config remote.origin.url "//somewhere else/repo" &&
618                 git submodule init &&
619                 test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
620         )
621 '
622
623 test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
624         (
625                 cd reltest &&
626                 cp pristine-.git-config .git/config &&
627                 cp pristine-.gitmodules .gitmodules &&
628                 git config remote.origin.url file:///tmp/repo &&
629                 git submodule init &&
630                 test "$(git config submodule.sub.url)" = file:///tmp/subrepo
631         )
632 '
633
634 test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
635         (
636                 cd reltest &&
637                 cp pristine-.git-config .git/config &&
638                 cp pristine-.gitmodules .gitmodules &&
639                 git config remote.origin.url helper:://hostname/repo &&
640                 git submodule init &&
641                 test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
642         )
643 '
644
645 test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
646         (
647                 cd reltest &&
648                 cp pristine-.git-config .git/config &&
649                 git config remote.origin.url user@host:repo &&
650                 git submodule init &&
651                 test "$(git config submodule.sub.url)" = user@host:subrepo
652         )
653 '
654
655 test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
656         (
657                 cd reltest &&
658                 cp pristine-.git-config .git/config &&
659                 cp pristine-.gitmodules .gitmodules &&
660                 git config remote.origin.url user@host:path/to/repo &&
661                 git submodule init &&
662                 test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
663         )
664 '
665
666 test_expect_success '../subrepo works with relative local path - foo' '
667         (
668                 cd reltest &&
669                 cp pristine-.git-config .git/config &&
670                 cp pristine-.gitmodules .gitmodules &&
671                 git config remote.origin.url foo &&
672                 # actual: fails with an error
673                 git submodule init &&
674                 test "$(git config submodule.sub.url)" = subrepo
675         )
676 '
677
678 test_expect_success '../subrepo works with relative local path - foo/bar' '
679         (
680                 cd reltest &&
681                 cp pristine-.git-config .git/config &&
682                 cp pristine-.gitmodules .gitmodules &&
683                 git config remote.origin.url foo/bar &&
684                 git submodule init &&
685                 test "$(git config submodule.sub.url)" = foo/subrepo
686         )
687 '
688
689 test_expect_success '../subrepo works with relative local path - ./foo' '
690         (
691                 cd reltest &&
692                 cp pristine-.git-config .git/config &&
693                 cp pristine-.gitmodules .gitmodules &&
694                 git config remote.origin.url ./foo &&
695                 git submodule init &&
696                 test "$(git config submodule.sub.url)" = subrepo
697         )
698 '
699
700 test_expect_success '../subrepo works with relative local path - ./foo/bar' '
701         (
702                 cd reltest &&
703                 cp pristine-.git-config .git/config &&
704                 cp pristine-.gitmodules .gitmodules &&
705                 git config remote.origin.url ./foo/bar &&
706                 git submodule init &&
707                 test "$(git config submodule.sub.url)" = foo/subrepo
708         )
709 '
710
711 test_expect_success '../subrepo works with relative local path - ../foo' '
712         (
713                 cd reltest &&
714                 cp pristine-.git-config .git/config &&
715                 cp pristine-.gitmodules .gitmodules &&
716                 git config remote.origin.url ../foo &&
717                 git submodule init &&
718                 test "$(git config submodule.sub.url)" = ../subrepo
719         )
720 '
721
722 test_expect_success '../subrepo works with relative local path - ../foo/bar' '
723         (
724                 cd reltest &&
725                 cp pristine-.git-config .git/config &&
726                 cp pristine-.gitmodules .gitmodules &&
727                 git config remote.origin.url ../foo/bar &&
728                 git submodule init &&
729                 test "$(git config submodule.sub.url)" = ../foo/subrepo
730         )
731 '
732
733 test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
734         (
735                 cd reltest &&
736                 cp pristine-.git-config .git/config &&
737                 cp pristine-.gitmodules .gitmodules &&
738                 mkdir -p a/b/c &&
739                 (cd a/b/c; git init) &&
740                 git config remote.origin.url ../foo/bar.git &&
741                 git submodule add ../bar/a/b/c ./a/b/c &&
742                 git submodule init &&
743                 test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
744         )
745 '
746
747 test_expect_success 'moving the superproject does not break submodules' '
748         (
749                 cd addtest &&
750                 git submodule status >expect
751         )
752         mv addtest addtest2 &&
753         (
754                 cd addtest2 &&
755                 git submodule status >actual &&
756                 test_cmp expect actual
757         )
758 '
759
760 test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
761         (
762                 cd addtest2 &&
763                 (
764                         cd repo &&
765                         echo "$submodurl/repo" >expect &&
766                         git config remote.origin.url >actual &&
767                         test_cmp expect actual &&
768                         echo "gitdir: ../.git/modules/repo" >expect &&
769                         test_cmp expect .git
770                 ) &&
771                 rm -rf repo &&
772                 git rm repo &&
773                 git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
774                 test_must_be_empty actual &&
775                 echo "gitdir: ../.git/modules/submod" >expect &&
776                 test_cmp expect submod/.git &&
777                 (
778                         cd repo &&
779                         echo "$submodurl/bare.git" >expect &&
780                         git config remote.origin.url >actual &&
781                         test_cmp expect actual &&
782                         echo "gitdir: ../.git/modules/repo_new" >expect &&
783                         test_cmp expect .git
784                 ) &&
785                 echo "repo" >expect &&
786                 test_must_fail git config -f .gitmodules submodule.repo.path &&
787                 git config -f .gitmodules submodule.repo_new.path >actual &&
788                 test_cmp expect actual&&
789                 echo "$submodurl/repo" >expect &&
790                 test_must_fail git config -f .gitmodules submodule.repo.url &&
791                 echo "$submodurl/bare.git" >expect &&
792                 git config -f .gitmodules submodule.repo_new.url >actual &&
793                 test_cmp expect actual &&
794                 echo "$submodurl/repo" >expect &&
795                 git config submodule.repo.url >actual &&
796                 test_cmp expect actual &&
797                 echo "$submodurl/bare.git" >expect &&
798                 git config submodule.repo_new.url >actual &&
799                 test_cmp expect actual
800         )
801 '
802
803 test_expect_success 'submodule add with an existing name fails unless forced' '
804         (
805                 cd addtest2 &&
806                 rm -rf repo &&
807                 git rm repo &&
808                 test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
809                 test ! -d repo &&
810                 test_must_fail git config -f .gitmodules submodule.repo_new.path &&
811                 test_must_fail git config -f .gitmodules submodule.repo_new.url &&
812                 echo "$submodurl/bare.git" >expect &&
813                 git config submodule.repo_new.url >actual &&
814                 test_cmp expect actual &&
815                 git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
816                 test -d repo &&
817                 echo "repo" >expect &&
818                 git config -f .gitmodules submodule.repo_new.path >actual &&
819                 test_cmp expect actual&&
820                 echo "$submodurl/repo.git" >expect &&
821                 git config -f .gitmodules submodule.repo_new.url >actual &&
822                 test_cmp expect actual &&
823                 echo "$submodurl/repo.git" >expect &&
824                 git config submodule.repo_new.url >actual &&
825                 test_cmp expect actual
826         )
827 '
828
829 test_expect_success 'set up a second submodule' '
830         git submodule add ./init2 example2 &&
831         git commit -m "submodule example2 added"
832 '
833
834 test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
835         git config submodule.example.foo bar &&
836         git config submodule.example2.frotz nitfol &&
837         git submodule deinit init &&
838         test -z "$(git config --get-regexp "submodule\.example\.")" &&
839         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
840         test -f example2/.git &&
841         rmdir init
842 '
843
844 test_expect_success 'submodule deinit from subdirectory' '
845         git submodule update --init &&
846         git config submodule.example.foo bar &&
847         mkdir -p sub &&
848         (
849                 cd sub &&
850                 git submodule deinit ../init >../output
851         ) &&
852         grep "\\.\\./init" output &&
853         test -z "$(git config --get-regexp "submodule\.example\.")" &&
854         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
855         test -f example2/.git &&
856         rmdir init
857 '
858
859 test_expect_success 'submodule deinit . deinits all initialized submodules' '
860         git submodule update --init &&
861         git config submodule.example.foo bar &&
862         git config submodule.example2.frotz nitfol &&
863         test_must_fail git submodule deinit &&
864         git submodule deinit . >actual &&
865         test -z "$(git config --get-regexp "submodule\.example\.")" &&
866         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
867         test_i18ngrep "Cleared directory .init" actual &&
868         test_i18ngrep "Cleared directory .example2" actual &&
869         rmdir init example2
870 '
871
872 test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' '
873         git submodule update --init &&
874         rm -rf init example2/* example2/.git &&
875         git submodule deinit init example2 >actual &&
876         test -z "$(git config --get-regexp "submodule\.example\.")" &&
877         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
878         test_i18ngrep ! "Cleared directory .init" actual &&
879         test_i18ngrep "Cleared directory .example2" actual &&
880         rmdir init
881 '
882
883 test_expect_success 'submodule deinit fails when the submodule contains modifications unless forced' '
884         git submodule update --init &&
885         echo X >>init/s &&
886         test_must_fail git submodule deinit init &&
887         test -n "$(git config --get-regexp "submodule\.example\.")" &&
888         test -f example2/.git &&
889         git submodule deinit -f init >actual &&
890         test -z "$(git config --get-regexp "submodule\.example\.")" &&
891         test_i18ngrep "Cleared directory .init" actual &&
892         rmdir init
893 '
894
895 test_expect_success 'submodule deinit fails when the submodule contains untracked files unless forced' '
896         git submodule update --init &&
897         echo X >>init/untracked &&
898         test_must_fail git submodule deinit init &&
899         test -n "$(git config --get-regexp "submodule\.example\.")" &&
900         test -f example2/.git &&
901         git submodule deinit -f init >actual &&
902         test -z "$(git config --get-regexp "submodule\.example\.")" &&
903         test_i18ngrep "Cleared directory .init" actual &&
904         rmdir init
905 '
906
907 test_expect_success 'submodule deinit fails when the submodule HEAD does not match unless forced' '
908         git submodule update --init &&
909         (
910                 cd init &&
911                 git checkout HEAD^
912         ) &&
913         test_must_fail git submodule deinit init &&
914         test -n "$(git config --get-regexp "submodule\.example\.")" &&
915         test -f example2/.git &&
916         git submodule deinit -f init >actual &&
917         test -z "$(git config --get-regexp "submodule\.example\.")" &&
918         test_i18ngrep "Cleared directory .init" actual &&
919         rmdir init
920 '
921
922 test_expect_success 'submodule deinit is silent when used on an uninitialized submodule' '
923         git submodule update --init &&
924         git submodule deinit init >actual &&
925         test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual &&
926         test_i18ngrep "Cleared directory .init" actual &&
927         git submodule deinit init >actual &&
928         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
929         test_i18ngrep "Cleared directory .init" actual &&
930         git submodule deinit . >actual &&
931         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
932         test_i18ngrep "Submodule .example2. (.*) unregistered for path .example2" actual &&
933         test_i18ngrep "Cleared directory .init" actual &&
934         git submodule deinit . >actual &&
935         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
936         test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
937         test_i18ngrep "Cleared directory .init" actual &&
938         rmdir init example2
939 '
940
941 test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' '
942         git submodule update --init &&
943         (
944                 cd init &&
945                 rm .git &&
946                 cp -R ../.git/modules/example .git &&
947                 GIT_WORK_TREE=. git config --unset core.worktree
948         ) &&
949         test_must_fail git submodule deinit init &&
950         test_must_fail git submodule deinit -f init &&
951         test -d init/.git &&
952         test -n "$(git config --get-regexp "submodule\.example\.")"
953 '
954
955 test_expect_success 'submodule with UTF-8 name' '
956         svname=$(printf "\303\245 \303\244\303\266") &&
957         mkdir "$svname" &&
958         (
959                 cd "$svname" &&
960                 git init &&
961                 >sub &&
962                 git add sub &&
963                 git commit -m "init sub"
964         ) &&
965         test_config core.precomposeunicode true &&
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