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