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