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