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