git-fetch-scripton commit Revert "Replace zero-length array decls with []." (2c04662)
   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=
   9force=
  10update_head_ok=
  11while case "$#" in 0) break ;; esac
  12do
  13        case "$1" in
  14        -a|--a|--ap|--app|--appe|--appen|--append)
  15                append=t
  16                ;;
  17        -f|--f|--fo|--for|--forc|--force)
  18                force=t
  19                ;;
  20        -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
  21        --update-he|--update-hea|--update-head|--update-head-|\
  22        --update-head-o|--update-head-ok)
  23                update_head_ok=t
  24                ;;
  25        *)
  26                break
  27                ;;
  28        esac
  29        shift
  30done
  31
  32case "$#" in
  330)
  34        test -f "$GIT_DIR/branches/origin" ||
  35                test -f "$GIT_DIR/remotes/origin" ||
  36                        die "Where do you want to fetch from today?"
  37        set origin ;;
  38esac
  39
  40remote_nick="$1"
  41remote=$(get_remote_url "$@")
  42refs=
  43rref=
  44rsync_slurped_objects=
  45
  46if test "" = "$append"
  47then
  48        : >$GIT_DIR/FETCH_HEAD
  49fi
  50
  51append_fetch_head () {
  52    head_="$1"
  53    remote_="$2"
  54    remote_name_="$3"
  55    remote_nick_="$4"
  56    local_name_="$5"
  57
  58    # 2.6.11-tree tag would not be happy to be fed to resolve.
  59    if git-cat-file commit "$head_" >/dev/null 2>&1
  60    then
  61        headc_=$(git-rev-parse --verify "$head_^0") || exit
  62        note_="$headc_  $remote_name_ from $remote_nick_"
  63        echo "$note_" >>$GIT_DIR/FETCH_HEAD
  64        echo >&2 "* committish: $note_"
  65    else
  66        echo >&2 "* non-commit: $note_"
  67    fi
  68    if test "$local_name_" != ""
  69    then
  70        # We are storing the head locally.  Make sure that it is
  71        # a fast forward (aka "reverse push").
  72        fast_forward_local "$local_name_" "$head_" "$remote_" "$remote_name_"
  73    fi
  74}
  75
  76fast_forward_local () {
  77    case "$1" in
  78    refs/tags/*)
  79        # Tags need not be pointing at commits so there
  80        # is no way to guarantee "fast-forward" anyway.
  81        if test -f "$GIT_DIR/$1"
  82        then
  83                echo >&2 "* $1: updating with $4"
  84                echo >&2 "  from $3."
  85        else
  86                echo >&2 "* $1: storing $4"
  87                echo >&2 "  from $3."
  88        fi
  89        echo "$2" >"$GIT_DIR/$1" ;;
  90
  91    refs/heads/*)
  92        # NEEDSWORK: use the same cmpxchg protocol here.
  93        echo "$2" >"$GIT_DIR/$1.lock"
  94        if test -f "$GIT_DIR/$1"
  95        then
  96            local=$(git-rev-parse --verify "$1^0") &&
  97            mb=$(git-merge-base "$local" "$2") &&
  98            case "$2,$mb" in
  99            $local,*)
 100                echo >&2 "* $1: same as $4"
 101                echo >&2 "  from $3"
 102                ;;
 103            *,$local)
 104                echo >&2 "* $1: fast forward to $4"
 105                echo >&2 "  from $3"
 106                ;;
 107            *)
 108                false
 109                ;;
 110            esac || {
 111                echo >&2 "* $1: does not fast forward to $4"
 112                case "$force,$single_force" in
 113                t,* | *,t)
 114                        echo >&2 "  from $3; forcing update."
 115                        ;;
 116                *)
 117                        mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
 118                        echo >&2 "  from $3; leaving it in '$1.remote'"
 119                        ;;
 120                esac
 121            }
 122        else
 123                echo >&2 "* $1: storing $4"
 124                echo >&2 "  from $3."
 125        fi
 126        test -f "$GIT_DIR/$1.lock" &&
 127            mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
 128        ;;
 129    esac
 130}
 131
 132case "$update_head_ok" in
 133'')
 134        orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
 135        ;;
 136esac
 137
 138for ref in $(get_remote_refs_for_fetch "$@")
 139do
 140    refs="$refs $ref"
 141
 142    # These are relative path from $GIT_DIR, typically starting at refs/
 143    # but may be HEAD
 144    if expr "$ref" : '\+' >/dev/null
 145    then
 146        single_force=t
 147        ref=$(expr "$ref" : '\+\(.*\)')
 148    else
 149        single_force=
 150    fi
 151    remote_name=$(expr "$ref" : '\([^:]*\):')
 152    local_name=$(expr "$ref" : '[^:]*:\(.*\)')
 153
 154    rref="$rref $remote_name"
 155
 156    # There are transports that can fetch only one head at a time...
 157    case "$remote" in
 158    http://* | https://*)
 159        if [ -n "$GIT_SSL_NO_VERIFY" ]; then
 160            curl_extra_args="-k"
 161        fi
 162        head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
 163        expr "$head" : "$_x40\$" >/dev/null ||
 164                die "Failed to fetch $remote_name from $remote"
 165        echo Fetching "$remote_name from $remote" using http
 166        git-http-pull -v -a "$head" "$remote/" || exit
 167        ;;
 168    rsync://*)
 169        TMP_HEAD="$GIT_DIR/TMP_HEAD"
 170        rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
 171        head=$(git-rev-parse TMP_HEAD)
 172        rm -f "$TMP_HEAD"
 173        test "$rsync_slurped_objects" || {
 174            rsync -avz --ignore-existing "$remote/objects/" \
 175                "$GIT_OBJECT_DIRECTORY/" || exit
 176            rsync_slurped_objects=t
 177        }
 178        ;;
 179    *)
 180        # We will do git native transport with just one call later.
 181        continue ;;
 182    esac
 183
 184    append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
 185
 186done
 187
 188case "$remote" in
 189http://* | https://* | rsync://* )
 190    ;; # we are already done.
 191*)
 192    git-fetch-pack "$remote" $rref |
 193    while read sha1 remote_name
 194    do
 195        found=
 196        single_force=
 197        for ref in $refs
 198        do
 199            case "$ref" in
 200            +$remote_name:*)
 201                single_force=t
 202                found="$ref"
 203                break ;;
 204            $remote_name:*)
 205                found="$ref"
 206                break ;;
 207            esac
 208        done
 209
 210        local_name=$(expr "$found" : '[^:]*:\(.*\)')
 211        append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
 212    done
 213    ;;
 214esac
 215
 216# If the original head was empty (i.e. no "master" yet), or
 217# if we were told not to worry, we do not have to check.
 218case ",$update_head_ok,$orig_head," in
 219*,, | t,* )
 220        ;;
 221*)
 222        curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
 223        if test "$curr_head" != "$orig_head"
 224        then
 225                echo "$orig_head" >$GIT_DIR/HEAD
 226                die "Cannot fetch into the current branch."
 227        fi
 228        ;;
 229esac