t / t7400-submodule-basic.shon commit Merge branch 'jn/rebase-cmdline-fix' (0f0169d)
   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'
  47
  48# The 'submodule add' tests need some repository to add as a submodule.
  49# The trash directory is a good one as any.
  50submodurl=$TRASH_DIRECTORY
  51
  52listbranches() {
  53        git for-each-ref --format='%(refname)' 'refs/heads/*'
  54}
  55
  56inspect() {
  57        dir=$1 &&
  58        dotdot="${2:-..}" &&
  59
  60        (
  61                cd "$dir" &&
  62                listbranches >"$dotdot/heads" &&
  63                { git symbolic-ref HEAD || :; } >"$dotdot/head" &&
  64                git rev-parse HEAD >"$dotdot/head-sha1" &&
  65                git update-index --refresh &&
  66                git diff-files --exit-code &&
  67                git clean -n -d -x >"$dotdot/untracked"
  68        )
  69}
  70
  71test_expect_success 'submodule add' '
  72        echo "refs/heads/master" >expect &&
  73        >empty &&
  74
  75        (
  76                cd addtest &&
  77                git submodule add "$submodurl" submod &&
  78                git submodule init
  79        ) &&
  80
  81        rm -f heads head untracked &&
  82        inspect addtest/submod ../.. &&
  83        test_cmp expect heads &&
  84        test_cmp expect head &&
  85        test_cmp empty untracked
  86'
  87
  88test_expect_success 'submodule add --branch' '
  89        echo "refs/heads/initial" >expect-head &&
  90        cat <<-\EOF >expect-heads &&
  91        refs/heads/initial
  92        refs/heads/master
  93        EOF
  94        >empty &&
  95
  96        (
  97                cd addtest &&
  98                git submodule add -b initial "$submodurl" submod-branch &&
  99                git submodule init
 100        ) &&
 101
 102        rm -f heads head untracked &&
 103        inspect addtest/submod-branch ../.. &&
 104        test_cmp expect-heads heads &&
 105        test_cmp expect-head head &&
 106        test_cmp empty untracked
 107'
 108
 109test_expect_success 'submodule add with ./ in path' '
 110        echo "refs/heads/master" >expect &&
 111        >empty &&
 112
 113        (
 114                cd addtest &&
 115                git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
 116                git submodule init
 117        ) &&
 118
 119        rm -f heads head untracked &&
 120        inspect addtest/dotsubmod/frotz ../../.. &&
 121        test_cmp expect heads &&
 122        test_cmp expect head &&
 123        test_cmp empty untracked
 124'
 125
 126test_expect_success 'submodule add with // in path' '
 127        echo "refs/heads/master" >expect &&
 128        >empty &&
 129
 130        (
 131                cd addtest &&
 132                git submodule add "$submodurl" slashslashsubmod///frotz// &&
 133                git submodule init
 134        ) &&
 135
 136        rm -f heads head untracked &&
 137        inspect addtest/slashslashsubmod/frotz ../../.. &&
 138        test_cmp expect heads &&
 139        test_cmp expect head &&
 140        test_cmp empty untracked
 141'
 142
 143test_expect_success 'submodule add with /.. in path' '
 144        echo "refs/heads/master" >expect &&
 145        >empty &&
 146
 147        (
 148                cd addtest &&
 149                git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
 150                git submodule init
 151        ) &&
 152
 153        rm -f heads head untracked &&
 154        inspect addtest/realsubmod ../.. &&
 155        test_cmp expect heads &&
 156        test_cmp expect head &&
 157        test_cmp empty untracked
 158'
 159
 160test_expect_success 'submodule add with ./, /.. and // in path' '
 161        echo "refs/heads/master" >expect &&
 162        >empty &&
 163
 164        (
 165                cd addtest &&
 166                git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
 167                git submodule init
 168        ) &&
 169
 170        rm -f heads head untracked &&
 171        inspect addtest/realsubmod2 ../.. &&
 172        test_cmp expect heads &&
 173        test_cmp expect head &&
 174        test_cmp empty untracked
 175'
 176
 177test_expect_success 'setup - add an example entry to .gitmodules' '
 178        GIT_CONFIG=.gitmodules \
 179        git config submodule.example.url git://example.com/init.git
 180'
 181
 182test_expect_success 'status should fail for unmapped paths' '
 183        test_must_fail git submodule status
 184'
 185
 186test_expect_success 'setup - map path in .gitmodules' '
 187        cat <<\EOF >expect &&
 188[submodule "example"]
 189        url = git://example.com/init.git
 190        path = init
 191EOF
 192
 193        GIT_CONFIG=.gitmodules git config submodule.example.path init &&
 194
 195        test_cmp expect .gitmodules
 196'
 197
 198test_expect_success 'status should only print one line' '
 199        git submodule status >lines &&
 200        test $(wc -l <lines) = 1
 201'
 202
 203test_expect_success 'setup - fetch commit name from submodule' '
 204        rev1=$(cd .subrepo && git rev-parse HEAD) &&
 205        printf "rev1: %s\n" "$rev1" &&
 206        test -n "$rev1"
 207'
 208
 209test_expect_success 'status should initially be "missing"' '
 210        git submodule status >lines &&
 211        grep "^-$rev1" lines
 212'
 213
 214test_expect_success 'init should register submodule url in .git/config' '
 215        echo git://example.com/init.git >expect &&
 216
 217        git submodule init &&
 218        git config submodule.example.url >url &&
 219        git config submodule.example.url ./.subrepo &&
 220
 221        test_cmp expect url
 222'
 223
 224test_expect_success 'update should fail when path is used by a file' '
 225        echo hello >expect &&
 226
 227        echo "hello" >init &&
 228        test_must_fail git submodule update &&
 229
 230        test_cmp expect init
 231'
 232
 233test_expect_success 'update should fail when path is used by a nonempty directory' '
 234        echo hello >expect &&
 235
 236        rm -fr init &&
 237        mkdir init &&
 238        echo "hello" >init/a &&
 239
 240        test_must_fail git submodule update &&
 241
 242        test_cmp expect init/a
 243'
 244
 245test_expect_success 'update should work when path is an empty dir' '
 246        rm -fr init &&
 247        rm -f head-sha1 &&
 248        echo "$rev1" >expect &&
 249
 250        mkdir init &&
 251        git submodule update &&
 252
 253        inspect init &&
 254        test_cmp expect head-sha1
 255'
 256
 257test_expect_success 'status should be "up-to-date" after update' '
 258        git submodule status >list &&
 259        grep "^ $rev1" list
 260'
 261
 262test_expect_success 'status should be "modified" after submodule commit' '
 263        (
 264                cd init &&
 265                echo b >b &&
 266                git add b &&
 267                git commit -m "submodule commit 2"
 268        ) &&
 269
 270        rev2=$(cd init && git rev-parse HEAD) &&
 271        test -n "$rev2" &&
 272        git submodule status >list &&
 273
 274        grep "^+$rev2" list
 275'
 276
 277test_expect_success 'the --cached sha1 should be rev1' '
 278        git submodule --cached status >list &&
 279        grep "^+$rev1" list
 280'
 281
 282test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
 283        git diff >diff &&
 284        grep "^+Subproject commit $rev2" diff
 285'
 286
 287test_expect_success 'update should checkout rev1' '
 288        rm -f head-sha1 &&
 289        echo "$rev1" >expect &&
 290
 291        git submodule update init &&
 292        inspect init &&
 293
 294        test_cmp expect head-sha1
 295'
 296
 297test_expect_success 'status should be "up-to-date" after update' '
 298        git submodule status >list &&
 299        grep "^ $rev1" list
 300'
 301
 302test_expect_success 'checkout superproject with subproject already present' '
 303        git checkout initial &&
 304        git checkout master
 305'
 306
 307test_expect_success 'apply submodule diff' '
 308        >empty &&
 309
 310        git branch second &&
 311        (
 312                cd init &&
 313                echo s >s &&
 314                git add s &&
 315                git commit -m "change subproject"
 316        ) &&
 317        git update-index --add init &&
 318        git commit -m "change init" &&
 319        git format-patch -1 --stdout >P.diff &&
 320        git checkout second &&
 321        git apply --index P.diff &&
 322
 323        git diff --cached master >staged &&
 324        test_cmp empty staged
 325'
 326
 327test_expect_success 'update --init' '
 328        mv init init2 &&
 329        git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 330        git config --remove-section submodule.example &&
 331        test_must_fail git config submodule.example.url &&
 332
 333        git submodule update init > update.out &&
 334        cat update.out &&
 335        grep "not initialized" update.out &&
 336        ! test -d init/.git &&
 337
 338        git submodule update --init init &&
 339        test -d init/.git
 340'
 341
 342test_expect_success 'do not add files from a submodule' '
 343
 344        git reset --hard &&
 345        test_must_fail git add init/a
 346
 347'
 348
 349test_expect_success 'gracefully add submodule with a trailing slash' '
 350
 351        git reset --hard &&
 352        git commit -m "commit subproject" init &&
 353        (cd init &&
 354         echo b > a) &&
 355        git add init/ &&
 356        git diff --exit-code --cached init &&
 357        commit=$(cd init &&
 358         git commit -m update a >/dev/null &&
 359         git rev-parse HEAD) &&
 360        git add init/ &&
 361        test_must_fail git diff --exit-code --cached init &&
 362        test $commit = $(git ls-files --stage |
 363                sed -n "s/^160000 \([^ ]*\).*/\1/p")
 364
 365'
 366
 367test_expect_success 'ls-files gracefully handles trailing slash' '
 368
 369        test "init" = "$(git ls-files init/)"
 370
 371'
 372
 373test_expect_success 'moving to a commit without submodule does not leave empty dir' '
 374        rm -rf init &&
 375        mkdir init &&
 376        git reset --hard &&
 377        git checkout initial &&
 378        test ! -d init &&
 379        git checkout second
 380'
 381
 382test_expect_success 'submodule <invalid-path> warns' '
 383
 384        git submodule no-such-submodule 2> output.err &&
 385        grep "^error: .*no-such-submodule" output.err
 386
 387'
 388
 389test_expect_success 'add submodules without specifying an explicit path' '
 390        mkdir repo &&
 391        cd repo &&
 392        git init &&
 393        echo r >r &&
 394        git add r &&
 395        git commit -m "repo commit 1" &&
 396        cd .. &&
 397        git clone --bare repo/ bare.git &&
 398        cd addtest &&
 399        git submodule add "$submodurl/repo" &&
 400        git config -f .gitmodules submodule.repo.path repo &&
 401        git submodule add "$submodurl/bare.git" &&
 402        git config -f .gitmodules submodule.bare.path bare
 403'
 404
 405test_done