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