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