3 # Copyright (c) 2007 Lars Hjemli
 
   6 test_description='Basic porcelain support for submodules
 
   8 This test tries to verify basic sanity of the init, update and status
 
   9 subcommands of git submodule.
 
  14 test_expect_success 'submodule deinit works on empty repository' '
 
  15         git submodule deinit --all
 
  18 test_expect_success 'setup - initial commit' '
 
  21         git commit -m "initial commit" &&
 
  25 test_expect_success 'submodule init aborts on missing .gitmodules file' '
 
  26         test_when_finished "git update-index --remove sub" &&
 
  27         git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
 
  28         # missing the .gitmodules file here
 
  29         test_must_fail git submodule init 2>actual &&
 
  30         test_i18ngrep "No url found for submodule path" actual
 
  33 test_expect_success 'submodule update aborts on missing .gitmodules file' '
 
  34         test_when_finished "git update-index --remove sub" &&
 
  35         git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
 
  36         # missing the .gitmodules file here
 
  37         git submodule update sub 2>actual &&
 
  38         test_i18ngrep "Submodule path .sub. not initialized" actual
 
  41 test_expect_success 'submodule update aborts on missing gitmodules url' '
 
  42         test_when_finished "git update-index --remove sub" &&
 
  43         git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
 
  44         test_when_finished "rm -f .gitmodules" &&
 
  45         git config -f .gitmodules submodule.s.path sub &&
 
  46         test_must_fail git submodule init
 
  49 test_expect_success 'add aborts on repository with no commits' '
 
  50         cat >expect <<-\EOF &&
 
  51         '"'repo-no-commits'"' does not have a commit checked out
 
  53         git init repo-no-commits &&
 
  54         test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
 
  55         test_i18ncmp expect actual
 
  58 test_expect_success 'status should ignore inner git repo when not added' '
 
  66                 git commit -m "initial"
 
  68         test_must_fail git submodule status inner 2>output.err &&
 
  70         test_i18ngrep "^error: .*did not match any file(s) known to git" output.err
 
  73 test_expect_success 'setup - repository in init subdirectory' '
 
  80                 git commit -m "submodule commit 1" &&
 
  81                 git tag -a -m "rev-1" rev-1
 
  85 test_expect_success 'setup - commit with gitlink' '
 
  89         git commit -m "super commit 1"
 
  92 test_expect_success 'setup - hide init subdirectory' '
 
  96 test_expect_success 'setup - repository to add submodules to' '
 
  98         git init addtest-ignore
 
 101 # The 'submodule add' tests need some repository to add as a submodule.
 
 102 # The trash directory is a good one as any. We need to canonicalize
 
 103 # the name, though, as some tests compare it to the absolute path git
 
 104 # generates, which will expand symbolic links.
 
 108         git for-each-ref --format='%(refname)' 'refs/heads/*'
 
 117                 listbranches >"$dotdot/heads" &&
 
 118                 { git symbolic-ref HEAD || :; } >"$dotdot/head" &&
 
 119                 git rev-parse HEAD >"$dotdot/head-sha1" &&
 
 120                 git update-index --refresh &&
 
 121                 git diff-files --exit-code &&
 
 122                 git clean -n -d -x >"$dotdot/untracked"
 
 126 test_expect_success 'submodule add' '
 
 127         echo "refs/heads/master" >expect &&
 
 131                 git submodule add -q "$submodurl" submod >actual &&
 
 132                 test_must_be_empty actual &&
 
 133                 echo "gitdir: ../.git/modules/submod" >expect &&
 
 134                 test_cmp expect submod/.git &&
 
 137                         git config core.worktree >actual &&
 
 138                         echo "../../../submod" >expect &&
 
 139                         test_cmp expect actual &&
 
 145         rm -f heads head untracked &&
 
 146         inspect addtest/submod ../.. &&
 
 147         test_cmp expect heads &&
 
 148         test_cmp expect head &&
 
 149         test_must_be_empty untracked
 
 152 test_expect_success 'setup parent and one repository' '
 
 153         test_create_repo parent &&
 
 154         test_commit -C parent one
 
 157 test_expect_success 'redirected submodule add does not show progress' '
 
 158         git -C addtest submodule add "file://$submodurl/parent" submod-redirected \
 
 161         test_i18ngrep ! "Checking connectivity" err
 
 164 test_expect_success 'redirected submodule add --progress does show progress' '
 
 165         git -C addtest submodule add --progress "file://$submodurl/parent" \
 
 166                 submod-redirected-progress 2>err && \
 
 170 test_expect_success 'submodule add to .gitignored path fails' '
 
 173                 cat <<-\EOF >expect &&
 
 174                 The following paths are ignored by one of your .gitignore files:
 
 176                 hint: Use -f if you really want to add them.
 
 177                 hint: Turn this message off by running
 
 178                 hint: "git config advice.addIgnoredFile false"
 
 180                 # Does not use test_commit due to the ignore
 
 181                 echo "*" > .gitignore &&
 
 182                 git add --force .gitignore &&
 
 183                 git commit -m"Ignore everything" &&
 
 184                 ! git submodule add "$submodurl" submod >actual 2>&1 &&
 
 185                 test_i18ncmp expect actual
 
 189 test_expect_success 'submodule add to .gitignored path with --force' '
 
 192                 git submodule add --force "$submodurl" submod
 
 196 test_expect_success 'submodule add to reconfigure existing submodule with --force' '
 
 199                 bogus_url="$(pwd)/bogus-url" &&
 
 200                 git submodule add --force "$bogus_url" submod &&
 
 201                 git submodule add --force -b initial "$submodurl" submod-branch &&
 
 202                 test "$bogus_url" = "$(git config -f .gitmodules submodule.submod.url)" &&
 
 203                 test "$bogus_url" = "$(git config submodule.submod.url)" &&
 
 205                 git submodule add --force "$submodurl" submod &&
 
 206                 test "$submodurl" = "$(git config -f .gitmodules submodule.submod.url)" &&
 
 207                 test "$submodurl" = "$(git config submodule.submod.url)"
 
 211 test_expect_success 'submodule add relays add --dry-run stderr' '
 
 212         test_when_finished "rm -rf addtest/.git/index.lock" &&
 
 215                 : >.git/index.lock &&
 
 216                 ! git submodule add "$submodurl" sub-while-locked 2>output.err &&
 
 217                 test_i18ngrep "^fatal: .*index\.lock" output.err &&
 
 218                 test_path_is_missing sub-while-locked
 
 222 test_expect_success 'submodule add --branch' '
 
 223         echo "refs/heads/initial" >expect-head &&
 
 224         cat <<-\EOF >expect-heads &&
 
 231                 git submodule add -b initial "$submodurl" submod-branch &&
 
 232                 test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
 
 236         rm -f heads head untracked &&
 
 237         inspect addtest/submod-branch ../.. &&
 
 238         test_cmp expect-heads heads &&
 
 239         test_cmp expect-head head &&
 
 240         test_must_be_empty untracked
 
 243 test_expect_success 'submodule add with ./ in path' '
 
 244         echo "refs/heads/master" >expect &&
 
 248                 git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
 
 252         rm -f heads head untracked &&
 
 253         inspect addtest/dotsubmod/frotz ../../.. &&
 
 254         test_cmp expect heads &&
 
 255         test_cmp expect head &&
 
 256         test_must_be_empty untracked
 
 259 test_expect_success 'submodule add with /././ in path' '
 
 260         echo "refs/heads/master" >expect &&
 
 264                 git submodule add "$submodurl" dotslashdotsubmod/././frotz/./ &&
 
 268         rm -f heads head untracked &&
 
 269         inspect addtest/dotslashdotsubmod/frotz ../../.. &&
 
 270         test_cmp expect heads &&
 
 271         test_cmp expect head &&
 
 272         test_must_be_empty untracked
 
 275 test_expect_success 'submodule add with // in path' '
 
 276         echo "refs/heads/master" >expect &&
 
 280                 git submodule add "$submodurl" slashslashsubmod///frotz// &&
 
 284         rm -f heads head untracked &&
 
 285         inspect addtest/slashslashsubmod/frotz ../../.. &&
 
 286         test_cmp expect heads &&
 
 287         test_cmp expect head &&
 
 288         test_must_be_empty untracked
 
 291 test_expect_success 'submodule add with /.. in path' '
 
 292         echo "refs/heads/master" >expect &&
 
 296                 git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
 
 300         rm -f heads head untracked &&
 
 301         inspect addtest/realsubmod ../.. &&
 
 302         test_cmp expect heads &&
 
 303         test_cmp expect head &&
 
 304         test_must_be_empty untracked
 
 307 test_expect_success 'submodule add with ./, /.. and // in path' '
 
 308         echo "refs/heads/master" >expect &&
 
 312                 git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
 
 316         rm -f heads head untracked &&
 
 317         inspect addtest/realsubmod2 ../.. &&
 
 318         test_cmp expect heads &&
 
 319         test_cmp expect head &&
 
 320         test_must_be_empty untracked
 
 323 test_expect_success !CYGWIN 'submodule add with \\ in path' '
 
 324         test_when_finished "rm -rf parent sub\\with\\backslash" &&
 
 326         # Initialize a repo with a backslash in its name
 
 327         git init sub\\with\\backslash &&
 
 328         touch sub\\with\\backslash/empty.file &&
 
 329         git -C sub\\with\\backslash add empty.file &&
 
 330         git -C sub\\with\\backslash commit -m "Added empty.file" &&
 
 332         # Add that repository as a submodule
 
 334         git -C parent submodule add ../sub\\with\\backslash
 
 337 test_expect_success 'submodule add in subdirectory' '
 
 338         echo "refs/heads/master" >expect &&
 
 343                 git submodule add "$submodurl" ../realsubmod3 &&
 
 347         rm -f heads head untracked &&
 
 348         inspect addtest/realsubmod3 ../.. &&
 
 349         test_cmp expect heads &&
 
 350         test_cmp expect head &&
 
 351         test_must_be_empty untracked
 
 354 test_expect_success 'submodule add in subdirectory with relative path should fail' '
 
 357                 test_must_fail git submodule add ../../ submod3 2>../../output.err
 
 359         test_i18ngrep toplevel output.err
 
 362 test_expect_success 'setup - add an example entry to .gitmodules' '
 
 363         git config --file=.gitmodules submodule.example.url git://example.com/init.git
 
 366 test_expect_success 'status should fail for unmapped paths' '
 
 367         test_must_fail git submodule status
 
 370 test_expect_success 'setup - map path in .gitmodules' '
 
 371         cat <<\EOF >expect &&
 
 372 [submodule "example"]
 
 373         url = git://example.com/init.git
 
 377         git config --file=.gitmodules submodule.example.path init &&
 
 379         test_cmp expect .gitmodules
 
 382 test_expect_success 'status should only print one line' '
 
 383         git submodule status >lines &&
 
 384         test_line_count = 1 lines
 
 387 test_expect_success 'status from subdirectory should have the same SHA1' '
 
 388         test_when_finished "rmdir addtest/subdir" &&
 
 392                 git submodule status >output &&
 
 393                 awk "{print \$1}" <output >expect &&
 
 395                 git submodule status >../output &&
 
 396                 awk "{print \$1}" <../output >../actual &&
 
 397                 test_cmp ../expect ../actual &&
 
 398                 git -C ../submod checkout HEAD^ &&
 
 399                 git submodule status >../output &&
 
 400                 awk "{print \$1}" <../output >../actual2 &&
 
 402                 git submodule status >output &&
 
 403                 awk "{print \$1}" <output >expect2 &&
 
 404                 test_cmp expect2 actual2 &&
 
 405                 ! test_cmp actual actual2
 
 409 test_expect_success 'setup - fetch commit name from submodule' '
 
 410         rev1=$(cd .subrepo && git rev-parse HEAD) &&
 
 411         printf "rev1: %s\n" "$rev1" &&
 
 415 test_expect_success 'status should initially be "missing"' '
 
 416         git submodule status >lines &&
 
 420 test_expect_success 'init should register submodule url in .git/config' '
 
 421         echo git://example.com/init.git >expect &&
 
 423         git submodule init &&
 
 424         git config submodule.example.url >url &&
 
 425         git config submodule.example.url ./.subrepo &&
 
 430 test_expect_success 'status should still be "missing" after initializing' '
 
 433         git submodule status >lines &&
 
 438 test_failure_with_unknown_submodule () {
 
 439         test_must_fail git submodule $1 no-such-submodule 2>output.err &&
 
 440         test_i18ngrep "^error: .*no-such-submodule" output.err
 
 443 test_expect_success 'init should fail with unknown submodule' '
 
 444         test_failure_with_unknown_submodule init
 
 447 test_expect_success 'update should fail with unknown submodule' '
 
 448         test_failure_with_unknown_submodule update
 
 451 test_expect_success 'status should fail with unknown submodule' '
 
 452         test_failure_with_unknown_submodule status
 
 455 test_expect_success 'sync should fail with unknown submodule' '
 
 456         test_failure_with_unknown_submodule sync
 
 459 test_expect_success 'update should fail when path is used by a file' '
 
 460         echo hello >expect &&
 
 462         echo "hello" >init &&
 
 463         test_must_fail git submodule update &&
 
 468 test_expect_success 'update should fail when path is used by a nonempty directory' '
 
 469         echo hello >expect &&
 
 473         echo "hello" >init/a &&
 
 475         test_must_fail git submodule update &&
 
 477         test_cmp expect init/a
 
 480 test_expect_success 'update should work when path is an empty dir' '
 
 483         echo "$rev1" >expect &&
 
 486         git submodule update -q >update.out &&
 
 487         test_must_be_empty update.out &&
 
 490         test_cmp expect head-sha1
 
 493 test_expect_success 'status should be "up-to-date" after update' '
 
 494         git submodule status >list &&
 
 498 test_expect_success 'status "up-to-date" from subdirectory' '
 
 502                 git submodule status >../list
 
 504         grep "^ $rev1" list &&
 
 505         grep "\\.\\./init" list
 
 508 test_expect_success 'status "up-to-date" from subdirectory with path' '
 
 512                 git submodule status ../init >../list
 
 514         grep "^ $rev1" list &&
 
 515         grep "\\.\\./init" list
 
 518 test_expect_success 'status should be "modified" after submodule commit' '
 
 523                 git commit -m "submodule commit 2"
 
 526         rev2=$(cd init && git rev-parse HEAD) &&
 
 528         git submodule status >list &&
 
 533 test_expect_success 'the --cached sha1 should be rev1' '
 
 534         git submodule --cached status >list &&
 
 538 test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
 
 540         grep "^+Subproject commit $rev2" diff
 
 543 test_expect_success 'update should checkout rev1' '
 
 545         echo "$rev1" >expect &&
 
 547         git submodule update init &&
 
 550         test_cmp expect head-sha1
 
 553 test_expect_success 'status should be "up-to-date" after update' '
 
 554         git submodule status >list &&
 
 558 test_expect_success 'checkout superproject with subproject already present' '
 
 559         git checkout initial &&
 
 563 test_expect_success 'apply submodule diff' '
 
 569                 git commit -m "change subproject"
 
 571         git update-index --add init &&
 
 572         git commit -m "change init" &&
 
 573         git format-patch -1 --stdout >P.diff &&
 
 574         git checkout second &&
 
 575         git apply --index P.diff &&
 
 577         git diff --cached master >staged &&
 
 578         test_must_be_empty staged
 
 581 test_expect_success 'update --init' '
 
 583         git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 
 584         git config --remove-section submodule.example &&
 
 585         test_must_fail git config submodule.example.url &&
 
 587         git submodule update init 2> update.out &&
 
 588         test_i18ngrep "not initialized" update.out &&
 
 589         test_must_fail git rev-parse --resolve-git-dir init/.git &&
 
 591         git submodule update --init init &&
 
 592         git rev-parse --resolve-git-dir init/.git
 
 595 test_expect_success 'update --init from subdirectory' '
 
 597         git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 
 598         git config --remove-section submodule.example &&
 
 599         test_must_fail git config submodule.example.url &&
 
 604                 git submodule update ../init 2>update.out &&
 
 605                 test_i18ngrep "not initialized" update.out &&
 
 606                 test_must_fail git rev-parse --resolve-git-dir ../init/.git &&
 
 608                 git submodule update --init ../init
 
 610         git rev-parse --resolve-git-dir init/.git
 
 613 test_expect_success 'do not add files from a submodule' '
 
 616         test_must_fail git add init/a
 
 620 test_expect_success 'gracefully add/reset submodule with a trailing slash' '
 
 623         git commit -m "commit subproject" init &&
 
 627         git diff --exit-code --cached init &&
 
 629          git commit -m update a >/dev/null &&
 
 630          git rev-parse HEAD) &&
 
 632         test_must_fail git diff --exit-code --cached init &&
 
 633         test $commit = $(git ls-files --stage |
 
 634                 sed -n "s/^160000 \([^ ]*\).*/\1/p") &&
 
 636         git diff --exit-code --cached init
 
 640 test_expect_success 'ls-files gracefully handles trailing slash' '
 
 642         test "init" = "$(git ls-files init/)"
 
 646 test_expect_success 'moving to a commit without submodule does not leave empty dir' '
 
 650         git checkout initial &&
 
 655 test_expect_success 'submodule <invalid-subcommand> fails' '
 
 656         test_must_fail git submodule no-such-subcommand
 
 659 test_expect_success 'add submodules without specifying an explicit path' '
 
 666                 git commit -m "repo commit 1"
 
 668         git clone --bare repo/ bare.git &&
 
 671                 git submodule add "$submodurl/repo" &&
 
 672                 git config -f .gitmodules submodule.repo.path repo &&
 
 673                 git submodule add "$submodurl/bare.git" &&
 
 674                 git config -f .gitmodules submodule.bare.path bare
 
 678 test_expect_success 'add should fail when path is used by a file' '
 
 682                 test_must_fail  git submodule add "$submodurl/repo" file
 
 686 test_expect_success 'add should fail when path is used by an existing directory' '
 
 690                 test_must_fail git submodule add "$submodurl/repo" empty-dir
 
 694 test_expect_success 'use superproject as upstream when path is relative and no url is set there' '
 
 697                 git submodule add ../repo relative &&
 
 698                 test "$(git config -f .gitmodules submodule.relative.url)" = ../repo &&
 
 699                 git submodule sync relative &&
 
 700                 test "$(git config submodule.relative.url)" = "$submodurl/repo"
 
 704 test_expect_success 'set up for relative path tests' '
 
 716                 git config -f .gitmodules submodule.sub.path sub &&
 
 717                 git config -f .gitmodules submodule.sub.url ../subrepo &&
 
 718                 cp .git/config pristine-.git-config &&
 
 719                 cp .gitmodules pristine-.gitmodules
 
 723 test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
 
 726                 cp pristine-.git-config .git/config &&
 
 727                 cp pristine-.gitmodules .gitmodules &&
 
 728                 git config remote.origin.url ssh://hostname/repo &&
 
 729                 git submodule init &&
 
 730                 test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
 
 734 test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
 
 737                 cp pristine-.git-config .git/config &&
 
 738                 cp pristine-.gitmodules .gitmodules &&
 
 739                 git config remote.origin.url ssh://hostname:22/repo &&
 
 740                 git submodule init &&
 
 741                 test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
 
 745 # About the choice of the path in the next test:
 
 746 # - double-slash side-steps path mangling issues on Windows
 
 747 # - it is still an absolute local path
 
 748 # - there cannot be a server with a blank in its name just in case the
 
 749 #   path is used erroneously to access a //server/share style path
 
 750 test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
 
 753                 cp pristine-.git-config .git/config &&
 
 754                 cp pristine-.gitmodules .gitmodules &&
 
 755                 git config remote.origin.url "//somewhere else/repo" &&
 
 756                 git submodule init &&
 
 757                 test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
 
 761 test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
 
 764                 cp pristine-.git-config .git/config &&
 
 765                 cp pristine-.gitmodules .gitmodules &&
 
 766                 git config remote.origin.url file:///tmp/repo &&
 
 767                 git submodule init &&
 
 768                 test "$(git config submodule.sub.url)" = file:///tmp/subrepo
 
 772 test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
 
 775                 cp pristine-.git-config .git/config &&
 
 776                 cp pristine-.gitmodules .gitmodules &&
 
 777                 git config remote.origin.url helper:://hostname/repo &&
 
 778                 git submodule init &&
 
 779                 test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
 
 783 test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
 
 786                 cp pristine-.git-config .git/config &&
 
 787                 git config remote.origin.url user@host:repo &&
 
 788                 git submodule init &&
 
 789                 test "$(git config submodule.sub.url)" = user@host:subrepo
 
 793 test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
 
 796                 cp pristine-.git-config .git/config &&
 
 797                 cp pristine-.gitmodules .gitmodules &&
 
 798                 git config remote.origin.url user@host:path/to/repo &&
 
 799                 git submodule init &&
 
 800                 test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
 
 804 test_expect_success '../subrepo works with relative local path - foo' '
 
 807                 cp pristine-.git-config .git/config &&
 
 808                 cp pristine-.gitmodules .gitmodules &&
 
 809                 git config remote.origin.url foo &&
 
 810                 # actual: fails with an error
 
 811                 git submodule init &&
 
 812                 test "$(git config submodule.sub.url)" = subrepo
 
 816 test_expect_success '../subrepo works with relative local path - foo/bar' '
 
 819                 cp pristine-.git-config .git/config &&
 
 820                 cp pristine-.gitmodules .gitmodules &&
 
 821                 git config remote.origin.url foo/bar &&
 
 822                 git submodule init &&
 
 823                 test "$(git config submodule.sub.url)" = foo/subrepo
 
 827 test_expect_success '../subrepo works with relative local path - ./foo' '
 
 830                 cp pristine-.git-config .git/config &&
 
 831                 cp pristine-.gitmodules .gitmodules &&
 
 832                 git config remote.origin.url ./foo &&
 
 833                 git submodule init &&
 
 834                 test "$(git config submodule.sub.url)" = subrepo
 
 838 test_expect_success '../subrepo works with relative local path - ./foo/bar' '
 
 841                 cp pristine-.git-config .git/config &&
 
 842                 cp pristine-.gitmodules .gitmodules &&
 
 843                 git config remote.origin.url ./foo/bar &&
 
 844                 git submodule init &&
 
 845                 test "$(git config submodule.sub.url)" = foo/subrepo
 
 849 test_expect_success '../subrepo works with relative local path - ../foo' '
 
 852                 cp pristine-.git-config .git/config &&
 
 853                 cp pristine-.gitmodules .gitmodules &&
 
 854                 git config remote.origin.url ../foo &&
 
 855                 git submodule init &&
 
 856                 test "$(git config submodule.sub.url)" = ../subrepo
 
 860 test_expect_success '../subrepo works with relative local path - ../foo/bar' '
 
 863                 cp pristine-.git-config .git/config &&
 
 864                 cp pristine-.gitmodules .gitmodules &&
 
 865                 git config remote.origin.url ../foo/bar &&
 
 866                 git submodule init &&
 
 867                 test "$(git config submodule.sub.url)" = ../foo/subrepo
 
 871 test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
 
 874                 cp pristine-.git-config .git/config &&
 
 875                 cp pristine-.gitmodules .gitmodules &&
 
 877                 (cd a/b/c && git init && test_commit msg) &&
 
 878                 git config remote.origin.url ../foo/bar.git &&
 
 879                 git submodule add ../bar/a/b/c ./a/b/c &&
 
 880                 git submodule init &&
 
 881                 test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
 
 885 test_expect_success 'moving the superproject does not break submodules' '
 
 888                 git submodule status >expect
 
 890         mv addtest addtest2 &&
 
 893                 git submodule status >actual &&
 
 894                 test_cmp expect actual
 
 898 test_expect_success 'moving the submodule does not break the superproject' '
 
 903         sed -e "s/^ \([^ ]* repo\) .*/-\1/" <actual >expect &&
 
 904         mv addtest2/repo addtest2/repo.bak &&
 
 905         test_when_finished "mv addtest2/repo.bak addtest2/repo" &&
 
 910         test_cmp expect actual
 
 913 test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
 
 918                         echo "$submodurl/repo" >expect &&
 
 919                         git config remote.origin.url >actual &&
 
 920                         test_cmp expect actual &&
 
 921                         echo "gitdir: ../.git/modules/repo" >expect &&
 
 926                 git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
 
 927                 test_must_be_empty actual &&
 
 928                 echo "gitdir: ../.git/modules/submod" >expect &&
 
 929                 test_cmp expect submod/.git &&
 
 932                         echo "$submodurl/bare.git" >expect &&
 
 933                         git config remote.origin.url >actual &&
 
 934                         test_cmp expect actual &&
 
 935                         echo "gitdir: ../.git/modules/repo_new" >expect &&
 
 938                 echo "repo" >expect &&
 
 939                 test_must_fail git config -f .gitmodules submodule.repo.path &&
 
 940                 git config -f .gitmodules submodule.repo_new.path >actual &&
 
 941                 test_cmp expect actual &&
 
 942                 echo "$submodurl/repo" >expect &&
 
 943                 test_must_fail git config -f .gitmodules submodule.repo.url &&
 
 944                 echo "$submodurl/bare.git" >expect &&
 
 945                 git config -f .gitmodules submodule.repo_new.url >actual &&
 
 946                 test_cmp expect actual &&
 
 947                 echo "$submodurl/repo" >expect &&
 
 948                 git config submodule.repo.url >actual &&
 
 949                 test_cmp expect actual &&
 
 950                 echo "$submodurl/bare.git" >expect &&
 
 951                 git config submodule.repo_new.url >actual &&
 
 952                 test_cmp expect actual
 
 956 test_expect_success 'recursive relative submodules stay relative' '
 
 957         test_when_finished "rm -rf super clone2 subsub sub3" &&
 
 964                 git commit -m "initial commit"
 
 972                 git commit -m "initial commit" &&
 
 973                 git submodule add ../subsub dirdir/subsub &&
 
 974                 git commit -m "add submodule subsub"
 
 982                 git commit -m "initial commit" &&
 
 983                 git submodule add ../sub3 &&
 
 984                 git commit -m "add submodule sub"
 
 986         git clone super clone2 &&
 
 989                 git submodule update --init --recursive &&
 
 990                 echo "gitdir: ../.git/modules/sub3" >./sub3/.git_expect &&
 
 991                 echo "gitdir: ../../../.git/modules/sub3/modules/dirdir/subsub" >./sub3/dirdir/subsub/.git_expect
 
 993         test_cmp clone2/sub3/.git_expect clone2/sub3/.git &&
 
 994         test_cmp clone2/sub3/dirdir/subsub/.git_expect clone2/sub3/dirdir/subsub/.git
 
 997 test_expect_success 'submodule add with an existing name fails unless forced' '
 
1002                 test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
 
1004                 test_must_fail git config -f .gitmodules submodule.repo_new.path &&
 
1005                 test_must_fail git config -f .gitmodules submodule.repo_new.url &&
 
1006                 echo "$submodurl/bare.git" >expect &&
 
1007                 git config submodule.repo_new.url >actual &&
 
1008                 test_cmp expect actual &&
 
1009                 git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
 
1011                 echo "repo" >expect &&
 
1012                 git config -f .gitmodules submodule.repo_new.path >actual &&
 
1013                 test_cmp expect actual &&
 
1014                 echo "$submodurl/repo.git" >expect &&
 
1015                 git config -f .gitmodules submodule.repo_new.url >actual &&
 
1016                 test_cmp expect actual &&
 
1017                 echo "$submodurl/repo.git" >expect &&
 
1018                 git config submodule.repo_new.url >actual &&
 
1019                 test_cmp expect actual
 
1023 test_expect_success 'set up a second submodule' '
 
1024         git submodule add ./init2 example2 &&
 
1025         git commit -m "submodule example2 added"
 
1028 test_expect_success 'submodule deinit works on repository without submodules' '
 
1029         test_when_finished "rm -rf newdirectory" &&
 
1030         mkdir newdirectory &&
 
1036                 git commit -m "repo should not be empty" &&
 
1037                 git submodule deinit . &&
 
1038                 git submodule deinit --all
 
1042 test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
 
1043         git config submodule.example.foo bar &&
 
1044         git config submodule.example2.frotz nitfol &&
 
1045         git submodule deinit init &&
 
1046         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1047         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
 
1048         test -f example2/.git &&
 
1052 test_expect_success 'submodule deinit should unset core.worktree' '
 
1053         test_path_is_file .git/modules/example/config &&
 
1054         test_must_fail git config -f .git/modules/example/config core.worktree
 
1057 test_expect_success 'submodule deinit from subdirectory' '
 
1058         git submodule update --init &&
 
1059         git config submodule.example.foo bar &&
 
1063                 git submodule deinit ../init >../output
 
1065         test_i18ngrep "\\.\\./init" output &&
 
1066         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1067         test -n "$(git config --get-regexp "submodule\.example2\.")" &&
 
1068         test -f example2/.git &&
 
1072 test_expect_success 'submodule deinit . deinits all initialized submodules' '
 
1073         git submodule update --init &&
 
1074         git config submodule.example.foo bar &&
 
1075         git config submodule.example2.frotz nitfol &&
 
1076         test_must_fail git submodule deinit &&
 
1077         git submodule deinit . >actual &&
 
1078         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1079         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
 
1080         test_i18ngrep "Cleared directory .init" actual &&
 
1081         test_i18ngrep "Cleared directory .example2" actual &&
 
1085 test_expect_success 'submodule deinit --all deinits all initialized submodules' '
 
1086         git submodule update --init &&
 
1087         git config submodule.example.foo bar &&
 
1088         git config submodule.example2.frotz nitfol &&
 
1089         test_must_fail git submodule deinit &&
 
1090         git submodule deinit --all >actual &&
 
1091         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1092         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
 
1093         test_i18ngrep "Cleared directory .init" actual &&
 
1094         test_i18ngrep "Cleared directory .example2" actual &&
 
1098 test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' '
 
1099         git submodule update --init &&
 
1100         rm -rf init example2/* example2/.git &&
 
1101         git submodule deinit init example2 >actual &&
 
1102         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1103         test -z "$(git config --get-regexp "submodule\.example2\.")" &&
 
1104         test_i18ngrep ! "Cleared directory .init" actual &&
 
1105         test_i18ngrep "Cleared directory .example2" actual &&
 
1109 test_expect_success 'submodule deinit fails when the submodule contains modifications unless forced' '
 
1110         git submodule update --init &&
 
1112         test_must_fail git submodule deinit init &&
 
1113         test -n "$(git config --get-regexp "submodule\.example\.")" &&
 
1114         test -f example2/.git &&
 
1115         git submodule deinit -f init >actual &&
 
1116         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1117         test_i18ngrep "Cleared directory .init" actual &&
 
1121 test_expect_success 'submodule deinit fails when the submodule contains untracked files unless forced' '
 
1122         git submodule update --init &&
 
1123         echo X >>init/untracked &&
 
1124         test_must_fail git submodule deinit init &&
 
1125         test -n "$(git config --get-regexp "submodule\.example\.")" &&
 
1126         test -f example2/.git &&
 
1127         git submodule deinit -f init >actual &&
 
1128         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1129         test_i18ngrep "Cleared directory .init" actual &&
 
1133 test_expect_success 'submodule deinit fails when the submodule HEAD does not match unless forced' '
 
1134         git submodule update --init &&
 
1139         test_must_fail git submodule deinit init &&
 
1140         test -n "$(git config --get-regexp "submodule\.example\.")" &&
 
1141         test -f example2/.git &&
 
1142         git submodule deinit -f init >actual &&
 
1143         test -z "$(git config --get-regexp "submodule\.example\.")" &&
 
1144         test_i18ngrep "Cleared directory .init" actual &&
 
1148 test_expect_success 'submodule deinit is silent when used on an uninitialized submodule' '
 
1149         git submodule update --init &&
 
1150         git submodule deinit init >actual &&
 
1151         test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual &&
 
1152         test_i18ngrep "Cleared directory .init" actual &&
 
1153         git submodule deinit init >actual &&
 
1154         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
 
1155         test_i18ngrep "Cleared directory .init" actual &&
 
1156         git submodule deinit . >actual &&
 
1157         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
 
1158         test_i18ngrep "Submodule .example2. (.*) unregistered for path .example2" actual &&
 
1159         test_i18ngrep "Cleared directory .init" actual &&
 
1160         git submodule deinit . >actual &&
 
1161         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
 
1162         test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
 
1163         test_i18ngrep "Cleared directory .init" actual &&
 
1164         git submodule deinit --all >actual &&
 
1165         test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
 
1166         test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
 
1167         test_i18ngrep "Cleared directory .init" actual &&
 
1171 test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' '
 
1172         git submodule update --init &&
 
1176                 cp -R ../.git/modules/example .git &&
 
1177                 GIT_WORK_TREE=. git config --unset core.worktree
 
1179         test_must_fail git submodule deinit init &&
 
1180         test_must_fail git submodule deinit -f init &&
 
1181         test -d init/.git &&
 
1182         test -n "$(git config --get-regexp "submodule\.example\.")"
 
1185 test_expect_success 'submodule with UTF-8 name' '
 
1186         svname=$(printf "\303\245 \303\244\303\266") &&
 
1193                 git commit -m "init sub"
 
1195         git submodule add ./"$svname" &&
 
1196         git submodule >&2 &&
 
1197         test -n "$(git submodule | grep "$svname")"
 
1200 test_expect_success 'submodule add clone shallow submodule' '
 
1206                 git submodule add --depth=1 file://"$pwd"/example2 submodule &&
 
1209                         test 1 = $(git log --oneline | wc -l)
 
1214 test_expect_success 'submodule helper list is not confused by common prefixes' '
 
1219                 echo hi >testfile2 &&
 
1221                 git commit -m "test1"
 
1227                 echo hello >testfile1 &&
 
1229                 git commit -m "test2"
 
1231         git submodule add /dir1/b dir1/b &&
 
1232         git submodule add /dir2/b dir2/b &&
 
1233         git commit -m "first submodule commit" &&
 
1234         git submodule--helper list dir1/b |cut -c51- >actual &&
 
1235         echo "dir1/b" >expect &&
 
1236         test_cmp expect actual
 
1239 test_expect_success 'setup superproject with submodules' '
 
1241         test_commit -C sub1 test &&
 
1242         test_commit -C sub1 test2 &&
 
1243         git init multisuper &&
 
1244         git -C multisuper submodule add ../sub1 sub0 &&
 
1245         git -C multisuper submodule add ../sub1 sub1 &&
 
1246         git -C multisuper submodule add ../sub1 sub2 &&
 
1247         git -C multisuper submodule add ../sub1 sub3 &&
 
1248         git -C multisuper commit -m "add some submodules"
 
1258 test_expect_success 'submodule update --init with a specification' '
 
1259         test_when_finished "rm -rf multisuper_clone" &&
 
1261         git clone file://"$pwd"/multisuper multisuper_clone &&
 
1262         git -C multisuper_clone submodule update --init . ":(exclude)sub0" &&
 
1263         git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
 
1264         test_cmp expect actual
 
1267 test_expect_success 'submodule update --init with submodule.active set' '
 
1268         test_when_finished "rm -rf multisuper_clone" &&
 
1270         git clone file://"$pwd"/multisuper multisuper_clone &&
 
1271         git -C multisuper_clone config submodule.active "." &&
 
1272         git -C multisuper_clone config --add submodule.active ":(exclude)sub0" &&
 
1273         git -C multisuper_clone submodule update --init &&
 
1274         git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
 
1275         test_cmp expect actual
 
1278 test_expect_success 'submodule update and setting submodule.<name>.active' '
 
1279         test_when_finished "rm -rf multisuper_clone" &&
 
1281         git clone file://"$pwd"/multisuper multisuper_clone &&
 
1282         git -C multisuper_clone config --bool submodule.sub0.active "true" &&
 
1283         git -C multisuper_clone config --bool submodule.sub1.active "false" &&
 
1284         git -C multisuper_clone config --bool submodule.sub2.active "true" &&
 
1286         cat >expect <<-\EOF &&
 
1292         git -C multisuper_clone submodule update &&
 
1293         git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
 
1294         test_cmp expect actual
 
1297 test_expect_success 'clone active submodule without submodule url set' '
 
1298         test_when_finished "rm -rf test/test" &&
 
1300         # another dir breaks accidental relative paths still being correct
 
1301         git clone file://"$pwd"/multisuper test/test &&
 
1304                 git config submodule.active "." &&
 
1306                 # do not pass --init flag, as the submodule is already active:
 
1307                 git submodule update &&
 
1308                 git submodule status >actual_raw &&
 
1310                 cut -c 1,43- actual_raw >actual &&
 
1311                 cat >expect <<-\EOF &&
 
1317                 test_cmp expect actual
 
1321 test_expect_success 'clone --recurse-submodules with a pathspec works' '
 
1322         test_when_finished "rm -rf multisuper_clone" &&
 
1323         cat >expected <<-\EOF &&
 
1330         git clone --recurse-submodules="sub0" multisuper multisuper_clone &&
 
1331         git -C multisuper_clone submodule status |cut -c1,43- >actual &&
 
1332         test_cmp expected actual
 
1335 test_expect_success 'clone with multiple --recurse-submodules options' '
 
1336         test_when_finished "rm -rf multisuper_clone" &&
 
1337         cat >expect <<-\EOF &&
 
1344         git clone --recurse-submodules="." \
 
1345                   --recurse-submodules=":(exclude)sub0" \
 
1346                   --recurse-submodules=":(exclude)sub2" \
 
1347                   multisuper multisuper_clone &&
 
1348         git -C multisuper_clone submodule status |cut -c1,43- >actual &&
 
1349         test_cmp expect actual
 
1352 test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' '
 
1353         test_when_finished "rm -rf multisuper_clone" &&
 
1354         cat <<-\EOF >expect &&
 
1361         cat <<-\EOF >expect2 &&
 
1370         git clone --recurse-submodules="." \
 
1371                   --recurse-submodules=":(exclude)sub0" \
 
1372                   --recurse-submodules=":(exclude)sub2" \
 
1373                   --recurse-submodules=":(exclude)sub4" \
 
1374                   multisuper multisuper_clone &&
 
1376         git -C multisuper_clone submodule status |cut -c1,43- >actual &&
 
1377         test_cmp expect actual &&
 
1379         git -C multisuper submodule add ../sub1 sub4 &&
 
1380         git -C multisuper submodule add ../sub1 sub5 &&
 
1381         git -C multisuper commit -m "add more submodules" &&
 
1382         # obtain the new superproject
 
1383         git -C multisuper_clone pull &&
 
1384         git -C multisuper_clone submodule update --init &&
 
1385         git -C multisuper_clone submodule status |cut -c1,43- >actual &&
 
1386         test_cmp expect2 actual
 
1389 test_expect_success 'init properly sets the config' '
 
1390         test_when_finished "rm -rf multisuper_clone" &&
 
1391         git clone --recurse-submodules="." \
 
1392                   --recurse-submodules=":(exclude)sub0" \
 
1393                   multisuper multisuper_clone &&
 
1395         git -C multisuper_clone submodule init -- sub0 sub1 &&
 
1396         git -C multisuper_clone config --get submodule.sub0.active &&
 
1397         test_must_fail git -C multisuper_clone config --get submodule.sub1.active
 
1400 test_expect_success 'recursive clone respects -q' '
 
1401         test_when_finished "rm -rf multisuper_clone" &&
 
1402         git clone -q --recurse-submodules multisuper multisuper_clone >actual &&
 
1403         test_must_be_empty actual