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