1f468e5619fc07ba86a340503b4f271ff921717c
   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        rev1=$(cd init && git rev-parse HEAD) &&
  32        printf "rev1: %s\n" "$rev1" &&
  33        test -n "$rev1"
  34'
  35
  36test_expect_success 'setup - commit with gitlink' '
  37        echo a >a &&
  38        echo z >z &&
  39        git add a init z &&
  40        git commit -m "super commit 1"
  41'
  42
  43test_expect_success 'setup - hide init subdirectory' '
  44        mv init .subrepo
  45'
  46
  47test_expect_success 'setup - add an example entry to .gitmodules' '
  48        GIT_CONFIG=.gitmodules \
  49        git config submodule.example.url git://example.com/init.git
  50'
  51
  52test_expect_success 'Prepare submodule add testing' '
  53        submodurl=$(pwd)
  54        (
  55                mkdir addtest &&
  56                cd addtest &&
  57                git init
  58        )
  59'
  60
  61test_expect_success 'submodule add' '
  62        (
  63                cd addtest &&
  64                git submodule add "$submodurl" submod &&
  65                git submodule init
  66        )
  67'
  68
  69test_expect_success 'submodule add --branch' '
  70        (
  71                cd addtest &&
  72                git submodule add -b initial "$submodurl" submod-branch &&
  73                git submodule init &&
  74                cd submod-branch &&
  75                git branch | grep initial
  76        )
  77'
  78
  79test_expect_success 'submodule add with ./ in path' '
  80        (
  81                cd addtest &&
  82                git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
  83                git submodule init
  84        )
  85'
  86
  87test_expect_success 'submodule add with // in path' '
  88        (
  89                cd addtest &&
  90                git submodule add "$submodurl" slashslashsubmod///frotz// &&
  91                git submodule init
  92        )
  93'
  94
  95test_expect_success 'submodule add with /.. in path' '
  96        (
  97                cd addtest &&
  98                git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
  99                git submodule init
 100        )
 101'
 102
 103test_expect_success 'submodule add with ./, /.. and // in path' '
 104        (
 105                cd addtest &&
 106                git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
 107                git submodule init
 108        )
 109'
 110
 111test_expect_success 'status should fail for unmapped paths' '
 112        if git submodule status
 113        then
 114                echo "[OOPS] submodule status succeeded"
 115                false
 116        elif ! GIT_CONFIG=.gitmodules git config submodule.example.path init
 117        then
 118                echo "[OOPS] git config failed to update .gitmodules"
 119                false
 120        fi
 121'
 122
 123test_expect_success 'status should only print one line' '
 124        lines=$(git submodule status | wc -l) &&
 125        test $lines = 1
 126'
 127
 128test_expect_success 'status should initially be "missing"' '
 129        git submodule status | grep "^-$rev1"
 130'
 131
 132test_expect_success 'init should register submodule url in .git/config' '
 133        git submodule init &&
 134        url=$(git config submodule.example.url) &&
 135        if test "$url" != "git://example.com/init.git"
 136        then
 137                echo "[OOPS] init succeeded but submodule url is wrong"
 138                false
 139        elif test_must_fail git config submodule.example.url ./.subrepo
 140        then
 141                echo "[OOPS] init succeeded but update of url failed"
 142                false
 143        fi
 144'
 145
 146test_expect_success 'update should fail when path is used by a file' '
 147        echo "hello" >init &&
 148        if git submodule update
 149        then
 150                echo "[OOPS] update should have failed"
 151                false
 152        elif test "$(cat init)" != "hello"
 153        then
 154                echo "[OOPS] update failed but init file was molested"
 155                false
 156        else
 157                rm init
 158        fi
 159'
 160
 161test_expect_success 'update should fail when path is used by a nonempty directory' '
 162        mkdir init &&
 163        echo "hello" >init/a &&
 164        if git submodule update
 165        then
 166                echo "[OOPS] update should have failed"
 167                false
 168        elif test "$(cat init/a)" != "hello"
 169        then
 170                echo "[OOPS] update failed but init/a was molested"
 171                false
 172        else
 173                rm init/a
 174        fi
 175'
 176
 177test_expect_success 'update should work when path is an empty dir' '
 178        rm -rf init &&
 179        mkdir init &&
 180        git submodule update &&
 181        head=$(cd init && git rev-parse HEAD) &&
 182        if test -z "$head"
 183        then
 184                echo "[OOPS] Failed to obtain submodule head"
 185                false
 186        elif test "$head" != "$rev1"
 187        then
 188                echo "[OOPS] Submodule head is $head but should have been $rev1"
 189                false
 190        fi
 191'
 192
 193test_expect_success 'status should be "up-to-date" after update' '
 194        git submodule status | grep "^ $rev1"
 195'
 196
 197test_expect_success 'status should be "modified" after submodule commit' '
 198        cd init &&
 199        echo b >b &&
 200        git add b &&
 201        git commit -m "submodule commit 2" &&
 202        rev2=$(git rev-parse HEAD) &&
 203        cd .. &&
 204        if test -z "$rev2"
 205        then
 206                echo "[OOPS] submodule git rev-parse returned nothing"
 207                false
 208        fi &&
 209        git submodule status | grep "^+$rev2"
 210'
 211
 212test_expect_success 'the --cached sha1 should be rev1' '
 213        git submodule --cached status | grep "^+$rev1"
 214'
 215
 216test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
 217        git diff | grep "^+Subproject commit $rev2"
 218'
 219
 220test_expect_success 'update should checkout rev1' '
 221        git submodule update init &&
 222        head=$(cd init && git rev-parse HEAD) &&
 223        if test -z "$head"
 224        then
 225                echo "[OOPS] submodule git rev-parse returned nothing"
 226                false
 227        elif test "$head" != "$rev1"
 228        then
 229                echo "[OOPS] init did not checkout correct head"
 230                false
 231        fi
 232'
 233
 234test_expect_success 'status should be "up-to-date" after update' '
 235        git submodule status | grep "^ $rev1"
 236'
 237
 238test_expect_success 'checkout superproject with subproject already present' '
 239        git checkout initial &&
 240        git checkout master
 241'
 242
 243test_expect_success 'apply submodule diff' '
 244        git branch second &&
 245        (
 246                cd init &&
 247                echo s >s &&
 248                git add s &&
 249                git commit -m "change subproject"
 250        ) &&
 251        git update-index --add init &&
 252        git commit -m "change init" &&
 253        git format-patch -1 --stdout >P.diff &&
 254        git checkout second &&
 255        git apply --index P.diff &&
 256        D=$(git diff --cached master) &&
 257        test -z "$D"
 258'
 259
 260test_expect_success 'update --init' '
 261
 262        mv init init2 &&
 263        git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 264        git config --remove-section submodule.example
 265        git submodule update init > update.out &&
 266        grep "not initialized" update.out &&
 267        test ! -d init/.git &&
 268        git submodule update --init init &&
 269        test -d init/.git
 270
 271'
 272
 273test_expect_success 'do not add files from a submodule' '
 274
 275        git reset --hard &&
 276        test_must_fail git add init/a
 277
 278'
 279
 280test_expect_success 'gracefully add submodule with a trailing slash' '
 281
 282        git reset --hard &&
 283        git commit -m "commit subproject" init &&
 284        (cd init &&
 285         echo b > a) &&
 286        git add init/ &&
 287        git diff --exit-code --cached init &&
 288        commit=$(cd init &&
 289         git commit -m update a >/dev/null &&
 290         git rev-parse HEAD) &&
 291        git add init/ &&
 292        test_must_fail git diff --exit-code --cached init &&
 293        test $commit = $(git ls-files --stage |
 294                sed -n "s/^160000 \([^ ]*\).*/\1/p")
 295
 296'
 297
 298test_expect_success 'ls-files gracefully handles trailing slash' '
 299
 300        test "init" = "$(git ls-files init/)"
 301
 302'
 303
 304test_expect_success 'moving to a commit without submodule does not leave empty dir' '
 305        rm -rf init &&
 306        mkdir init &&
 307        git reset --hard &&
 308        git checkout initial &&
 309        test ! -d init &&
 310        git checkout second
 311'
 312
 313test_expect_success 'submodule <invalid-path> warns' '
 314
 315        git submodule no-such-submodule 2> output.err &&
 316        grep "^error: .*no-such-submodule" output.err
 317
 318'
 319
 320test_expect_success 'add submodules without specifying an explicit path' '
 321        mkdir repo &&
 322        cd repo &&
 323        git init &&
 324        echo r >r &&
 325        git add r &&
 326        git commit -m "repo commit 1" &&
 327        cd .. &&
 328        git clone --bare repo/ bare.git &&
 329        cd addtest &&
 330        git submodule add "$submodurl/repo" &&
 331        git config -f .gitmodules submodule.repo.path repo &&
 332        git submodule add "$submodurl/bare.git" &&
 333        git config -f .gitmodules submodule.bare.path bare
 334'
 335
 336test_done