t / t7400-submodule-basic.shon commit Merge branch 'mo/perl-bidi-pipe-envfix' (8e949a4)
   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.
  51submodurl=$TRASH_DIRECTORY
  52
  53listbranches() {
  54        git for-each-ref --format='%(refname)' 'refs/heads/*'
  55}
  56
  57inspect() {
  58        dir=$1 &&
  59        dotdot="${2:-..}" &&
  60
  61        (
  62                cd "$dir" &&
  63                listbranches >"$dotdot/heads" &&
  64                { git symbolic-ref HEAD || :; } >"$dotdot/head" &&
  65                git rev-parse HEAD >"$dotdot/head-sha1" &&
  66                git update-index --refresh &&
  67                git diff-files --exit-code &&
  68                git clean -n -d -x >"$dotdot/untracked"
  69        )
  70}
  71
  72test_expect_success 'submodule add' '
  73        echo "refs/heads/master" >expect &&
  74        >empty &&
  75
  76        (
  77                cd addtest &&
  78                git submodule add "$submodurl" submod &&
  79                git submodule init
  80        ) &&
  81
  82        rm -f heads head untracked &&
  83        inspect addtest/submod ../.. &&
  84        test_cmp expect heads &&
  85        test_cmp expect head &&
  86        test_cmp empty untracked
  87'
  88
  89test_expect_success 'submodule add to .gitignored path fails' '
  90        (
  91                cd addtest-ignore &&
  92                cat <<-\EOF >expect &&
  93                The following path is ignored by one of your .gitignore files:
  94                submod
  95                Use -f if you really want to add it.
  96                EOF
  97                # Does not use test_commit due to the ignore
  98                echo "*" > .gitignore &&
  99                git add --force .gitignore &&
 100                git commit -m"Ignore everything" &&
 101                ! git submodule add "$submodurl" submod >actual 2>&1 &&
 102                test_cmp expect actual
 103        )
 104'
 105
 106test_expect_success 'submodule add to .gitignored path with --force' '
 107        (
 108                cd addtest-ignore &&
 109                git submodule add --force "$submodurl" submod
 110        )
 111'
 112
 113test_expect_success 'submodule add --branch' '
 114        echo "refs/heads/initial" >expect-head &&
 115        cat <<-\EOF >expect-heads &&
 116        refs/heads/initial
 117        refs/heads/master
 118        EOF
 119        >empty &&
 120
 121        (
 122                cd addtest &&
 123                git submodule add -b initial "$submodurl" submod-branch &&
 124                git submodule init
 125        ) &&
 126
 127        rm -f heads head untracked &&
 128        inspect addtest/submod-branch ../.. &&
 129        test_cmp expect-heads heads &&
 130        test_cmp expect-head head &&
 131        test_cmp empty untracked
 132'
 133
 134test_expect_success 'submodule add with ./ in path' '
 135        echo "refs/heads/master" >expect &&
 136        >empty &&
 137
 138        (
 139                cd addtest &&
 140                git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
 141                git submodule init
 142        ) &&
 143
 144        rm -f heads head untracked &&
 145        inspect addtest/dotsubmod/frotz ../../.. &&
 146        test_cmp expect heads &&
 147        test_cmp expect head &&
 148        test_cmp empty untracked
 149'
 150
 151test_expect_success 'submodule add with // in path' '
 152        echo "refs/heads/master" >expect &&
 153        >empty &&
 154
 155        (
 156                cd addtest &&
 157                git submodule add "$submodurl" slashslashsubmod///frotz// &&
 158                git submodule init
 159        ) &&
 160
 161        rm -f heads head untracked &&
 162        inspect addtest/slashslashsubmod/frotz ../../.. &&
 163        test_cmp expect heads &&
 164        test_cmp expect head &&
 165        test_cmp empty untracked
 166'
 167
 168test_expect_success 'submodule add with /.. in path' '
 169        echo "refs/heads/master" >expect &&
 170        >empty &&
 171
 172        (
 173                cd addtest &&
 174                git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
 175                git submodule init
 176        ) &&
 177
 178        rm -f heads head untracked &&
 179        inspect addtest/realsubmod ../.. &&
 180        test_cmp expect heads &&
 181        test_cmp expect head &&
 182        test_cmp empty untracked
 183'
 184
 185test_expect_success 'submodule add with ./, /.. and // in path' '
 186        echo "refs/heads/master" >expect &&
 187        >empty &&
 188
 189        (
 190                cd addtest &&
 191                git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
 192                git submodule init
 193        ) &&
 194
 195        rm -f heads head untracked &&
 196        inspect addtest/realsubmod2 ../.. &&
 197        test_cmp expect heads &&
 198        test_cmp expect head &&
 199        test_cmp empty untracked
 200'
 201
 202test_expect_success 'setup - add an example entry to .gitmodules' '
 203        GIT_CONFIG=.gitmodules \
 204        git config submodule.example.url git://example.com/init.git
 205'
 206
 207test_expect_success 'status should fail for unmapped paths' '
 208        test_must_fail git submodule status
 209'
 210
 211test_expect_success 'setup - map path in .gitmodules' '
 212        cat <<\EOF >expect &&
 213[submodule "example"]
 214        url = git://example.com/init.git
 215        path = init
 216EOF
 217
 218        GIT_CONFIG=.gitmodules git config submodule.example.path init &&
 219
 220        test_cmp expect .gitmodules
 221'
 222
 223test_expect_success 'status should only print one line' '
 224        git submodule status >lines &&
 225        test $(wc -l <lines) = 1
 226'
 227
 228test_expect_success 'setup - fetch commit name from submodule' '
 229        rev1=$(cd .subrepo && git rev-parse HEAD) &&
 230        printf "rev1: %s\n" "$rev1" &&
 231        test -n "$rev1"
 232'
 233
 234test_expect_success 'status should initially be "missing"' '
 235        git submodule status >lines &&
 236        grep "^-$rev1" lines
 237'
 238
 239test_expect_success 'init should register submodule url in .git/config' '
 240        echo git://example.com/init.git >expect &&
 241
 242        git submodule init &&
 243        git config submodule.example.url >url &&
 244        git config submodule.example.url ./.subrepo &&
 245
 246        test_cmp expect url
 247'
 248
 249test_expect_success 'update should fail when path is used by a file' '
 250        echo hello >expect &&
 251
 252        echo "hello" >init &&
 253        test_must_fail git submodule update &&
 254
 255        test_cmp expect init
 256'
 257
 258test_expect_success 'update should fail when path is used by a nonempty directory' '
 259        echo hello >expect &&
 260
 261        rm -fr init &&
 262        mkdir init &&
 263        echo "hello" >init/a &&
 264
 265        test_must_fail git submodule update &&
 266
 267        test_cmp expect init/a
 268'
 269
 270test_expect_success 'update should work when path is an empty dir' '
 271        rm -fr init &&
 272        rm -f head-sha1 &&
 273        echo "$rev1" >expect &&
 274
 275        mkdir init &&
 276        git submodule update &&
 277
 278        inspect init &&
 279        test_cmp expect head-sha1
 280'
 281
 282test_expect_success 'status should be "up-to-date" after update' '
 283        git submodule status >list &&
 284        grep "^ $rev1" list
 285'
 286
 287test_expect_success 'status should be "modified" after submodule commit' '
 288        (
 289                cd init &&
 290                echo b >b &&
 291                git add b &&
 292                git commit -m "submodule commit 2"
 293        ) &&
 294
 295        rev2=$(cd init && git rev-parse HEAD) &&
 296        test -n "$rev2" &&
 297        git submodule status >list &&
 298
 299        grep "^+$rev2" list
 300'
 301
 302test_expect_success 'the --cached sha1 should be rev1' '
 303        git submodule --cached status >list &&
 304        grep "^+$rev1" list
 305'
 306
 307test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
 308        git diff >diff &&
 309        grep "^+Subproject commit $rev2" diff
 310'
 311
 312test_expect_success 'update should checkout rev1' '
 313        rm -f head-sha1 &&
 314        echo "$rev1" >expect &&
 315
 316        git submodule update init &&
 317        inspect init &&
 318
 319        test_cmp expect head-sha1
 320'
 321
 322test_expect_success 'status should be "up-to-date" after update' '
 323        git submodule status >list &&
 324        grep "^ $rev1" list
 325'
 326
 327test_expect_success 'checkout superproject with subproject already present' '
 328        git checkout initial &&
 329        git checkout master
 330'
 331
 332test_expect_success 'apply submodule diff' '
 333        >empty &&
 334
 335        git branch second &&
 336        (
 337                cd init &&
 338                echo s >s &&
 339                git add s &&
 340                git commit -m "change subproject"
 341        ) &&
 342        git update-index --add init &&
 343        git commit -m "change init" &&
 344        git format-patch -1 --stdout >P.diff &&
 345        git checkout second &&
 346        git apply --index P.diff &&
 347
 348        git diff --cached master >staged &&
 349        test_cmp empty staged
 350'
 351
 352test_expect_success 'update --init' '
 353        mv init init2 &&
 354        git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 355        git config --remove-section submodule.example &&
 356        test_must_fail git config submodule.example.url &&
 357
 358        git submodule update init > update.out &&
 359        cat update.out &&
 360        grep "not initialized" update.out &&
 361        ! test -d init/.git &&
 362
 363        git submodule update --init init &&
 364        test -d init/.git
 365'
 366
 367test_expect_success 'do not add files from a submodule' '
 368
 369        git reset --hard &&
 370        test_must_fail git add init/a
 371
 372'
 373
 374test_expect_success 'gracefully add submodule with a trailing slash' '
 375
 376        git reset --hard &&
 377        git commit -m "commit subproject" init &&
 378        (cd init &&
 379         echo b > a) &&
 380        git add init/ &&
 381        git diff --exit-code --cached init &&
 382        commit=$(cd init &&
 383         git commit -m update a >/dev/null &&
 384         git rev-parse HEAD) &&
 385        git add init/ &&
 386        test_must_fail git diff --exit-code --cached init &&
 387        test $commit = $(git ls-files --stage |
 388                sed -n "s/^160000 \([^ ]*\).*/\1/p")
 389
 390'
 391
 392test_expect_success 'ls-files gracefully handles trailing slash' '
 393
 394        test "init" = "$(git ls-files init/)"
 395
 396'
 397
 398test_expect_success 'moving to a commit without submodule does not leave empty dir' '
 399        rm -rf init &&
 400        mkdir init &&
 401        git reset --hard &&
 402        git checkout initial &&
 403        test ! -d init &&
 404        git checkout second
 405'
 406
 407test_expect_success 'submodule <invalid-path> warns' '
 408
 409        git submodule no-such-submodule 2> output.err &&
 410        grep "^error: .*no-such-submodule" output.err
 411
 412'
 413
 414test_expect_success 'add submodules without specifying an explicit path' '
 415        mkdir repo &&
 416        (
 417                cd repo &&
 418                git init &&
 419                echo r >r &&
 420                git add r &&
 421                git commit -m "repo commit 1"
 422        ) &&
 423        git clone --bare repo/ bare.git &&
 424        (
 425                cd addtest &&
 426                git submodule add "$submodurl/repo" &&
 427                git config -f .gitmodules submodule.repo.path repo &&
 428                git submodule add "$submodurl/bare.git" &&
 429                git config -f .gitmodules submodule.bare.path bare
 430        )
 431'
 432
 433test_expect_success 'add should fail when path is used by a file' '
 434        (
 435                cd addtest &&
 436                touch file &&
 437                test_must_fail  git submodule add "$submodurl/repo" file
 438        )
 439'
 440
 441test_expect_success 'add should fail when path is used by an existing directory' '
 442        (
 443                cd addtest &&
 444                mkdir empty-dir &&
 445                test_must_fail git submodule add "$submodurl/repo" empty-dir
 446        )
 447'
 448
 449test_expect_success 'set up for relative path tests' '
 450        mkdir reltest &&
 451        (
 452                cd reltest &&
 453                git init &&
 454                mkdir sub &&
 455                (
 456                        cd sub &&
 457                        git init &&
 458                        test_commit foo
 459                ) &&
 460                git add sub &&
 461                git config -f .gitmodules submodule.sub.path sub &&
 462                git config -f .gitmodules submodule.sub.url ../subrepo &&
 463                cp .git/config pristine-.git-config
 464        )
 465'
 466
 467test_expect_success 'relative path works with URL' '
 468        (
 469                cd reltest &&
 470                cp pristine-.git-config .git/config &&
 471                git config remote.origin.url ssh://hostname/repo &&
 472                git submodule init &&
 473                test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
 474        )
 475'
 476
 477test_expect_success 'relative path works with user@host:path' '
 478        (
 479                cd reltest &&
 480                cp pristine-.git-config .git/config &&
 481                git config remote.origin.url user@host:repo &&
 482                git submodule init &&
 483                test "$(git config submodule.sub.url)" = user@host:subrepo
 484        )
 485'
 486
 487test_done