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