X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=git-fetch.sh;h=14ea295113be9381ce9d4af52f022ce99c75506f;hb=706fe6ae03e2c1452d59892944701c56237b903f;hp=27407c1d357d8bf9d621875b1a773cef671ddc3d;hpb=0542f48c894f924d94a2bd05f7e4cbab25656112;p=git.git diff --git a/git-fetch.sh b/git-fetch.sh index 27407c1d..14ea2951 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -1,12 +1,18 @@ #!/bin/sh # -. git-sh-setup || die "Not a git archive" +. git-sh-setup . git-parse-remote _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" +LF=' +' +IFS="$LF" + +tags= append= force= +verbose= update_head_ok= while case "$#" in 0) break ;; esac do @@ -17,11 +23,17 @@ do -f|--f|--fo|--for|--forc|--force) force=t ;; + -t|--t|--ta|--tag|--tags) + tags=t + ;; -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\ --update-he|--update-hea|--update-head|--update-head-|\ --update-head-o|--update-head-ok) update_head_ok=t ;; + -v|--verbose) + verbose=Yes + ;; *) break ;; @@ -45,7 +57,7 @@ rsync_slurped_objects= if test "" = "$append" then - : >$GIT_DIR/FETCH_HEAD + : >"$GIT_DIR/FETCH_HEAD" fi append_fetch_head () { @@ -82,13 +94,13 @@ append_fetch_head () { if git-cat-file commit "$head_" >/dev/null 2>&1 then headc_=$(git-rev-parse --verify "$head_^0") || exit - echo "$headc_ $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD - echo >&2 "* committish: $head_" - echo >&2 " $note_" + echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD" + [ "$verbose" ] && echo >&2 "* committish: $head_" + [ "$verbose" ] && echo >&2 " $note_" else - echo "$head_ not-for-merge $note_" >>$GIT_DIR/FETCH_HEAD - echo >&2 "* non-commit: $head_" - echo >&2 " $note_" + echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD" + [ "$verbose" ] && echo >&2 "* non-commit: $head_" + [ "$verbose" ] && echo >&2 " $note_" fi if test "$local_name_" != "" then @@ -106,7 +118,12 @@ fast_forward_local () { # is no way to guarantee "fast-forward" anyway. if test -f "$GIT_DIR/$1" then - echo >&2 "* $1: updating with $3" + if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2" + then + [ "$verbose" ] && echo >&2 "* $1: same as $3" + else + echo >&2 "* $1: updating with $3" + fi else echo >&2 "* $1: storing $3" fi @@ -158,9 +175,32 @@ case "$update_head_ok" in ;; esac -for ref in $(get_remote_refs_for_fetch "$@") +# If --tags (and later --heads or --all) is specified, then we are +# not talking about defaults stored in Pull: line of remotes or +# branches file, and just fetch those and refspecs explicitly given. +# Otherwise we do what we always did. + +reflist=$(get_remote_refs_for_fetch "$@") +if test "$tags" +then + taglist=$(git-ls-remote --tags "$remote" | + sed -e ' + /\^/d + s/^[^ ]* // + s/.*/&:&/') + if test "$#" -gt 1 + then + # remote URL plus explicit refspecs; we need to merge them. + reflist="$reflist$LF$taglist" + else + # No explicit refspecs; fetch tags only. + reflist=$taglist + fi +fi + +for ref in $reflist do - refs="$refs $ref" + refs="$refs$LF$ref" # These are relative path from $GIT_DIR, typically starting at refs/ # but may be HEAD @@ -181,7 +221,7 @@ do remote_name=$(expr "$ref" : '\([^:]*\):') local_name=$(expr "$ref" : '[^:]*:\(.*\)') - rref="$rref $remote_name" + rref="$rref$LF$remote_name" # There are transports that can fetch only one head at a time... case "$remote" in @@ -189,7 +229,12 @@ do if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi - head=$(curl -nsf $curl_extra_args "$remote/$remote_name") && + remote_name_quoted=$(perl -e ' + my $u = $ARGV[0]; + $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg; + print "$u"; + ' "$remote_name") + head=$(curl -nsfL $curl_extra_args "$remote/$remote_name_quoted") && expr "$head" : "$_x40\$" >/dev/null || die "Failed to fetch $remote_name from $remote" echo >&2 Fetching "$remote_name from $remote" using http @@ -239,6 +284,7 @@ case "$remote" in http://* | https://* | rsync://* ) ;; # we are already done. *) + IFS=" $LF" ( git-fetch-pack "$remote" $rref || echo failed "$remote" ) |