a70909e4ff15035d135eed061de8b4ea70ac5060
   1#!/bin/sh
   2#
   3. git-sh-setup-script || die "Not a git archive"
   4. git-parse-remote-script
   5_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
   6_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
   7
   8append=
   9case "$#" in
  100)
  11        test -f "$GIT_DIR/branches/origin" ||
  12                test -f "$GIT_DIR/remotes/origin" ||
  13                        die "Where do you want to fetch from?"
  14        set origin ;;
  15*)
  16        case "$1" in
  17        -a|--a|--ap|--app|--appe|--appen|--append)
  18                append=t
  19                shift ;;
  20        esac
  21esac
  22remote_nick="$1"
  23remote=$(get_remote_url "$@")
  24refs=
  25rref=
  26rsync_slurped_objects=
  27
  28if test "" = "$append"
  29then
  30        : >$GIT_DIR/FETCH_HEAD
  31fi
  32
  33append_fetch_head () {
  34    head_="$1"
  35    remote_="$2"
  36    remote_name_="$3"
  37    remote_nick_="$4"
  38    local_name_="$5"
  39
  40    # 2.6.11-tree tag would not be happy to be fed to resolve.
  41    if git-cat-file commit "$head_" >/dev/null 2>&1
  42    then
  43        head_=$(git-rev-parse --verify "$head_^0") || exit
  44        note_="$head_   $remote_name_ from $remote_nick_"
  45        echo "$note_" >>$GIT_DIR/FETCH_HEAD
  46        echo >&2 "* committish: $note_"
  47    else
  48        echo >&2 "* non-commit: $note_"
  49    fi
  50    if test "$local_name_" != ""
  51    then
  52        # We are storing the head locally.  Make sure that it is
  53        # a fast forward (aka "reverse push").
  54        fast_forward_local "$local_name_" "$head_" "$remote_" "$remote_name_"
  55    fi
  56}
  57
  58fast_forward_local () {
  59    case "$1" in
  60    refs/tags/*)
  61        # Tags need not be pointing at commits so there
  62        # is no way to guarantee "fast-forward" anyway.
  63        echo "$2" >"$GIT_DIR/$1" ;;
  64    refs/heads/*)
  65        # NEEDSWORK: use the same cmpxchg protocol here.
  66        echo "$2" >"$GIT_DIR/$1.lock"
  67        if test -f "$GIT_DIR/$1"
  68        then
  69            local=$(git-rev-parse --verify "$1^0") &&
  70            mb=$(git-merge-base "$local" "$2") &&
  71            case "$2,$mb" in
  72            $local,*)
  73                echo >&2 "* $1: same as $4"
  74                echo >&2 "  from $3"
  75                ;;
  76            *,$local)
  77                echo >&2 "* $1: fast forward to $4"
  78                echo >&2 "  from $3"
  79                ;;
  80            *)
  81                false
  82                ;;
  83            esac || {
  84                mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
  85                echo >&2 "* $1: does not fast forward to $4"
  86                echo >&2 "  from $3; leaving it in '$1.remote'"
  87            }
  88        else
  89                echo >&2 "* $1: storing $4"
  90                echo >&2 "  from $3."
  91        fi
  92        test -f "$GIT_DIR/$1.lock" &&
  93            mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
  94        ;;
  95    esac
  96}
  97
  98for ref in $(get_remote_refs_for_fetch "$@")
  99do
 100    refs="$refs $ref"
 101
 102    # These are relative path from $GIT_DIR, typically starting at refs/
 103    # but may be HEAD
 104    remote_name=$(expr "$ref" : '\([^:]*\):')
 105    local_name=$(expr "$ref" : '[^:]*:\(.*\)')
 106
 107    rref="$rref $remote_name"
 108
 109    # There are transports that can fetch only one head at a time...
 110    case "$remote" in
 111    http://* | https://*)
 112        if [ -n "$GIT_SSL_NO_VERIFY" ]; then
 113            curl_extra_args="-k"
 114        fi
 115        head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
 116        expr "$head" : "$_x40\$" >/dev/null ||
 117            die "Failed to fetch $remote_name from $remote"
 118        echo Fetching "$remote_name from $remote" using http
 119        git-http-pull -v -a "$head" "$remote/" || exit
 120        ;;
 121    rsync://*)
 122        TMP_HEAD="$GIT_DIR/TMP_HEAD"
 123        rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
 124        head=$(git-rev-parse TMP_HEAD)
 125        rm -f "$TMP_HEAD"
 126        test "$rsync_slurped_objects" || {
 127            rsync -avz --ignore-existing "$remote/objects/" \
 128                "$GIT_OBJECT_DIRECTORY/" || exit
 129            rsync_slurped_objects=t
 130        }
 131        ;;
 132    *)
 133        # We will do git native transport with just one call later.
 134        continue ;;
 135    esac
 136
 137    append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
 138
 139done
 140
 141case "$remote" in
 142http://* | https://* | rsync://* )
 143    ;; # we are already done.
 144*)
 145    git-fetch-pack "$remote" $rref |
 146    while read sha1 remote_name
 147    do
 148        found=
 149        for ref in $refs
 150        do
 151            case "$ref" in
 152            $remote_name:*)
 153                found="$ref"
 154                break ;;
 155            esac
 156        done
 157
 158        local_name=$(expr "$found" : '[^:]*:\(.*\)')
 159        append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
 160    done
 161    ;;
 162esac