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