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