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