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