t / t5570-git-daemon.shon commit Merge branch 'jc/denoise-rm-to-resolve' (5e9d978)
   1#!/bin/sh
   2
   3test_description='test fetching over git protocol'
   4. ./test-lib.sh
   5
   6. "$TEST_DIRECTORY"/lib-git-daemon.sh
   7start_git_daemon
   8
   9check_verbose_connect () {
  10        test_i18ngrep -F "Looking up 127.0.0.1 ..." stderr &&
  11        test_i18ngrep -F "Connecting to 127.0.0.1 (port " stderr &&
  12        test_i18ngrep -F "done." stderr
  13}
  14
  15test_expect_success 'setup repository' '
  16        git config push.default matching &&
  17        echo content >file &&
  18        git add file &&
  19        git commit -m one
  20'
  21
  22test_expect_success 'create git-accessible bare repository' '
  23        mkdir "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
  24        (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
  25         git --bare init &&
  26         : >git-daemon-export-ok
  27        ) &&
  28        git remote add public "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
  29        git push public master:master
  30'
  31
  32test_expect_success 'clone git repository' '
  33        git clone -v "$GIT_DAEMON_URL/repo.git" clone 2>stderr &&
  34        check_verbose_connect &&
  35        test_cmp file clone/file
  36'
  37
  38test_expect_success 'fetch changes via git protocol' '
  39        echo content >>file &&
  40        git commit -a -m two &&
  41        git push public &&
  42        (cd clone && git pull -v) 2>stderr &&
  43        check_verbose_connect &&
  44        test_cmp file clone/file
  45'
  46
  47test_expect_success 'no-op fetch -v stderr is as expected' '
  48        (cd clone && git fetch -v) 2>stderr &&
  49        check_verbose_connect
  50'
  51
  52test_expect_success 'no-op fetch without "-v" is quiet' '
  53        (cd clone && git fetch 2>../stderr) &&
  54        test_must_be_empty stderr
  55'
  56
  57test_expect_success 'remote detects correct HEAD' '
  58        git push public master:other &&
  59        (cd clone &&
  60         git remote set-head -d origin &&
  61         git remote set-head -a origin &&
  62         git symbolic-ref refs/remotes/origin/HEAD > output &&
  63         echo refs/remotes/origin/master > expect &&
  64         test_cmp expect output
  65        )
  66'
  67
  68test_expect_success 'prepare pack objects' '
  69        cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
  70        (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
  71         git --bare repack -a -d
  72        )
  73'
  74
  75test_expect_success 'fetch notices corrupt pack' '
  76        cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
  77        (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
  78         p=$(ls objects/pack/pack-*.pack) &&
  79         chmod u+w $p &&
  80         printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
  81        ) &&
  82        mkdir repo_bad1.git &&
  83        (cd repo_bad1.git &&
  84         git --bare init &&
  85         test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad1.git" &&
  86         test 0 = $(ls objects/pack/pack-*.pack | wc -l)
  87        )
  88'
  89
  90test_expect_success 'fetch notices corrupt idx' '
  91        cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
  92        (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
  93         rm -f objects/pack/multi-pack-index &&
  94         p=$(ls objects/pack/pack-*.idx) &&
  95         chmod u+w $p &&
  96         printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
  97        ) &&
  98        mkdir repo_bad2.git &&
  99        (cd repo_bad2.git &&
 100         git --bare init &&
 101         test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad2.git" &&
 102         test 0 = $(ls objects/pack | wc -l)
 103        )
 104'
 105
 106test_remote_error()
 107{
 108        do_export=YesPlease
 109        while test $# -gt 0
 110        do
 111                case $1 in
 112                -x)
 113                        shift
 114                        chmod -x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git"
 115                        ;;
 116                -n)
 117                        shift
 118                        do_export=
 119                        ;;
 120                *)
 121                        break
 122                esac
 123        done
 124
 125        msg=$1
 126        shift
 127        cmd=$1
 128        shift
 129        repo=$1
 130        shift || error "invalid number of arguments"
 131
 132        if test -x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo"
 133        then
 134                if test -n "$do_export"
 135                then
 136                        : >"$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
 137                else
 138                        rm -f "$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
 139                fi
 140        fi
 141
 142        test_must_fail git "$cmd" "$GIT_DAEMON_URL/$repo" "$@" 2>output &&
 143        test_i18ngrep "fatal: remote error: $msg: /$repo" output &&
 144        ret=$?
 145        chmod +x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git"
 146        (exit $ret)
 147}
 148
 149msg="access denied or repository not exported"
 150test_expect_success 'clone non-existent' "test_remote_error    '$msg' clone nowhere.git    "
 151test_expect_success 'push disabled'      "test_remote_error    '$msg' push  repo.git master"
 152test_expect_success 'read access denied' "test_remote_error -x '$msg' fetch repo.git       "
 153test_expect_success 'not exported'       "test_remote_error -n '$msg' fetch repo.git       "
 154
 155stop_git_daemon
 156start_git_daemon --informative-errors
 157
 158test_expect_success 'clone non-existent' "test_remote_error    'no such repository'      clone nowhere.git    "
 159test_expect_success 'push disabled'      "test_remote_error    'service not enabled'     push  repo.git master"
 160test_expect_success 'read access denied' "test_remote_error -x 'no such repository'      fetch repo.git       "
 161test_expect_success 'not exported'       "test_remote_error -n 'repository not exported' fetch repo.git       "
 162
 163stop_git_daemon
 164start_git_daemon --interpolated-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH/%H%D"
 165
 166test_expect_success 'access repo via interpolated hostname' '
 167        repo="$GIT_DAEMON_DOCUMENT_ROOT_PATH/localhost/interp.git" &&
 168        git init --bare "$repo" &&
 169        git push "$repo" HEAD &&
 170        >"$repo"/git-daemon-export-ok &&
 171        GIT_OVERRIDE_VIRTUAL_HOST=localhost \
 172                git ls-remote "$GIT_DAEMON_URL/interp.git" &&
 173        GIT_OVERRIDE_VIRTUAL_HOST=LOCALHOST \
 174                git ls-remote "$GIT_DAEMON_URL/interp.git"
 175'
 176
 177test_expect_success 'hostname cannot break out of directory' '
 178        repo="$GIT_DAEMON_DOCUMENT_ROOT_PATH/../escape.git" &&
 179        git init --bare "$repo" &&
 180        git push "$repo" HEAD &&
 181        >"$repo"/git-daemon-export-ok &&
 182        test_must_fail \
 183                env GIT_OVERRIDE_VIRTUAL_HOST=.. \
 184                git ls-remote "$GIT_DAEMON_URL/escape.git"
 185'
 186
 187test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
 188        {
 189                printf "git-upload-pack /interp.git\n\0host=localhost" | packetize
 190                printf "0000"
 191        } >input &&
 192        fake_nc "$GIT_DAEMON_HOST_PORT" <input >output &&
 193        depacketize <output >output.raw &&
 194
 195        # just pick out the value of master, which avoids any protocol
 196        # particulars
 197        perl -lne "print \$1 if m{^(\\S+) refs/heads/master}" <output.raw >actual &&
 198        git -C "$repo" rev-parse master >expect &&
 199        test_cmp expect actual
 200'
 201
 202test_done