git-fetch.shon commit Update git-apply to use C-style quoting for funny pathnames. (ea56188)
   1#!/bin/sh
   2#
   3. git-sh-setup || die "Not a git archive"
   4. git-parse-remote
   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
   8tags=
   9append=
  10force=
  11update_head_ok=
  12while case "$#" in 0) break ;; esac
  13do
  14        case "$1" in
  15        -a|--a|--ap|--app|--appe|--appen|--append)
  16                append=t
  17                ;;
  18        -f|--f|--fo|--for|--forc|--force)
  19                force=t
  20                ;;
  21        -t|--t|--ta|--tag|--tags)
  22                tags=t
  23                ;;
  24        -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
  25        --update-he|--update-hea|--update-head|--update-head-|\
  26        --update-head-o|--update-head-ok)
  27                update_head_ok=t
  28                ;;
  29        *)
  30                break
  31                ;;
  32        esac
  33        shift
  34done
  35
  36case "$#" in
  370)
  38        test -f "$GIT_DIR/branches/origin" ||
  39                test -f "$GIT_DIR/remotes/origin" ||
  40                        die "Where do you want to fetch from today?"
  41        set origin ;;
  42esac
  43
  44remote_nick="$1"
  45remote=$(get_remote_url "$@")
  46refs=
  47rref=
  48rsync_slurped_objects=
  49
  50if test "" = "$append"
  51then
  52        : >"$GIT_DIR/FETCH_HEAD"
  53fi
  54
  55append_fetch_head () {
  56    head_="$1"
  57    remote_="$2"
  58    remote_name_="$3"
  59    remote_nick_="$4"
  60    local_name_="$5"
  61    case "$6" in
  62    t) not_for_merge_='not-for-merge' ;;
  63    '') not_for_merge_= ;;
  64    esac
  65
  66    # remote-nick is the URL given on the command line (or a shorthand)
  67    # remote-name is the $GIT_DIR relative refs/ path we computed
  68    # for this refspec.
  69    case "$remote_name_" in
  70    HEAD)
  71        note_= ;;
  72    refs/heads/*)
  73        note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')"
  74        note_="branch '$note_' of " ;;
  75    refs/tags/*)
  76        note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')"
  77        note_="tag '$note_' of " ;;
  78    *)
  79        note_="$remote_name of " ;;
  80    esac
  81    remote_1_=$(expr "$remote_" : '\(.*\)\.git/*$') &&
  82        remote_="$remote_1_"
  83    note_="$note_$remote_"
  84
  85    # 2.6.11-tree tag would not be happy to be fed to resolve.
  86    if git-cat-file commit "$head_" >/dev/null 2>&1
  87    then
  88        headc_=$(git-rev-parse --verify "$head_^0") || exit
  89        echo "$headc_   $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
  90        echo >&2 "* committish: $head_"
  91        echo >&2 "  $note_"
  92    else
  93        echo "$head_    not-for-merge   $note_" >>"$GIT_DIR/FETCH_HEAD"
  94        echo >&2 "* non-commit: $head_"
  95        echo >&2 "  $note_"
  96    fi
  97    if test "$local_name_" != ""
  98    then
  99        # We are storing the head locally.  Make sure that it is
 100        # a fast forward (aka "reverse push").
 101        fast_forward_local "$local_name_" "$head_" "$note_"
 102    fi
 103}
 104
 105fast_forward_local () {
 106    mkdir -p "$(dirname "$GIT_DIR/$1")"
 107    case "$1" in
 108    refs/tags/*)
 109        # Tags need not be pointing at commits so there
 110        # is no way to guarantee "fast-forward" anyway.
 111        if test -f "$GIT_DIR/$1"
 112        then
 113                echo >&2 "* $1: updating with $3"
 114        else
 115                echo >&2 "* $1: storing $3"
 116        fi
 117        git-update-ref "$1" "$2" 
 118        ;;
 119
 120    refs/heads/*)
 121        # $1 is the ref being updated.
 122        # $2 is the new value for the ref.
 123        local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
 124        if test "$local"
 125        then
 126            # Require fast-forward.
 127            mb=$(git-merge-base "$local" "$2") &&
 128            case "$2,$mb" in
 129            $local,*)
 130                echo >&2 "* $1: same as $3"
 131                ;;
 132            *,$local)
 133                echo >&2 "* $1: fast forward to $3"
 134                git-update-ref "$1" "$2" "$local"
 135                ;;
 136            *)
 137                false
 138                ;;
 139            esac || {
 140                echo >&2 "* $1: does not fast forward to $3;"
 141                case ",$force,$single_force," in
 142                *,t,*)
 143                        echo >&2 "  forcing update."
 144                        git-update-ref "$1" "$2" "$local"
 145                        ;;
 146                *)
 147                        echo >&2 "  not updating."
 148                        ;;
 149                esac
 150            }
 151        else
 152            echo >&2 "* $1: storing $3"
 153            git-update-ref "$1" "$2"
 154        fi
 155        ;;
 156    esac
 157}
 158
 159case "$update_head_ok" in
 160'')
 161        orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
 162        ;;
 163esac
 164
 165# If --tags (and later --heads or --all) is specified, then we are
 166# not talking about defaults stored in Pull: line of remotes or
 167# branches file, and just fetch those and refspecs explicitly given.
 168# Otherwise we do what we always did.
 169
 170reflist=$(get_remote_refs_for_fetch "$@")
 171if test "$tags"
 172then
 173        taglist=$(git-ls-remote --tags "$remote" |
 174                sed -e '
 175                        /\^{}$/d
 176                        s/^[^   ]*      //
 177                        s/.*/&:&/')
 178        if test "$#" -gt 1
 179        then
 180                # remote URL plus explicit refspecs; we need to merge them.
 181                reflist="$reflist $taglist"
 182        else
 183                # No explicit refspecs; fetch tags only.
 184                reflist=$taglist
 185        fi
 186fi
 187
 188for ref in $reflist
 189do
 190    refs="$refs $ref"
 191
 192    # These are relative path from $GIT_DIR, typically starting at refs/
 193    # but may be HEAD
 194    if expr "$ref" : '\.' >/dev/null
 195    then
 196        not_for_merge=t
 197        ref=$(expr "$ref" : '\.\(.*\)')
 198    else
 199        not_for_merge=
 200    fi
 201    if expr "$ref" : '\+' >/dev/null
 202    then
 203        single_force=t
 204        ref=$(expr "$ref" : '\+\(.*\)')
 205    else
 206        single_force=
 207    fi
 208    remote_name=$(expr "$ref" : '\([^:]*\):')
 209    local_name=$(expr "$ref" : '[^:]*:\(.*\)')
 210
 211    rref="$rref $remote_name"
 212
 213    # There are transports that can fetch only one head at a time...
 214    case "$remote" in
 215    http://* | https://*)
 216        if [ -n "$GIT_SSL_NO_VERIFY" ]; then
 217            curl_extra_args="-k"
 218        fi
 219        head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
 220        expr "$head" : "$_x40\$" >/dev/null ||
 221                die "Failed to fetch $remote_name from $remote"
 222        echo >&2 Fetching "$remote_name from $remote" using http
 223        git-http-fetch -v -a "$head" "$remote/" || exit
 224        ;;
 225    rsync://*)
 226        TMP_HEAD="$GIT_DIR/TMP_HEAD"
 227        rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
 228        head=$(git-rev-parse --verify TMP_HEAD)
 229        rm -f "$TMP_HEAD"
 230        test "$rsync_slurped_objects" || {
 231            rsync -av --ignore-existing --exclude info \
 232                "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
 233
 234            # Look at objects/info/alternates for rsync -- http will
 235            # support it natively and git native ones will do it on the remote
 236            # end.  Not having that file is not a crime.
 237            rsync -q "$remote/objects/info/alternates" \
 238                "$GIT_DIR/TMP_ALT" 2>/dev/null ||
 239                rm -f "$GIT_DIR/TMP_ALT"
 240            if test -f "$GIT_DIR/TMP_ALT"
 241            then
 242                resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
 243                while read alt
 244                do
 245                    case "$alt" in 'bad alternate: '*) die "$alt";; esac
 246                    echo >&2 "Getting alternate: $alt"
 247                    rsync -av --ignore-existing --exclude info \
 248                    "$alt" "$GIT_OBJECT_DIRECTORY/" || exit
 249                done
 250                rm -f "$GIT_DIR/TMP_ALT"
 251            fi
 252            rsync_slurped_objects=t
 253        }
 254        ;;
 255    *)
 256        # We will do git native transport with just one call later.
 257        continue ;;
 258    esac
 259
 260    append_fetch_head "$head" "$remote" \
 261        "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
 262
 263done
 264
 265case "$remote" in
 266http://* | https://* | rsync://* )
 267    ;; # we are already done.
 268*)
 269    (
 270        git-fetch-pack "$remote" $rref || echo failed "$remote"
 271    ) |
 272    while read sha1 remote_name
 273    do
 274        case "$sha1" in
 275        failed)
 276                echo >&2 "Fetch failure: $remote"
 277                exit 1 ;;
 278        esac
 279        found=
 280        single_force=
 281        for ref in $refs
 282        do
 283            case "$ref" in
 284            +$remote_name:*)
 285                single_force=t
 286                not_for_merge=
 287                found="$ref"
 288                break ;;
 289            .+$remote_name:*)
 290                single_force=t
 291                not_for_merge=t
 292                found="$ref"
 293                break ;;
 294            .$remote_name:*)
 295                not_for_merge=t
 296                found="$ref"
 297                break ;;
 298            $remote_name:*)
 299                not_for_merge=
 300                found="$ref"
 301                break ;;
 302            esac
 303        done
 304        local_name=$(expr "$found" : '[^:]*:\(.*\)')
 305        append_fetch_head "$sha1" "$remote" \
 306                "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
 307    done || exit
 308    ;;
 309esac
 310
 311# If the original head was empty (i.e. no "master" yet), or
 312# if we were told not to worry, we do not have to check.
 313case ",$update_head_ok,$orig_head," in
 314*,, | t,* )
 315        ;;
 316*)
 317        curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
 318        if test "$curr_head" != "$orig_head"
 319        then
 320                git-update-ref HEAD "$orig_head"
 321                die "Cannot fetch into the current branch."
 322        fi
 323        ;;
 324esac