X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-fetch.sh;h=8bd11f8b60c0ffec8a67f59bc7e12e1f63adfc91;hb=9d0524d42f340fc49f9e175d966afb7dce3854bb;hp=b15fc2b389f35e2b30b17eada4bcc711a12d2a11;hpb=05eb811aa1546b696c6c4d55593cfd4fbef0dce5;p=git.git diff --git a/git-fetch.sh b/git-fetch.sh index b15fc2b38..8bd11f8b6 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -2,7 +2,15 @@ # USAGE=' ...' +SUBDIRECTORY_OK=Yes . git-sh-setup +set_reflog_action "fetch $*" + +TOP=$(git-rev-parse --show-cdup) +if test ! -z "$TOP" +then + cd "$TOP" +fi . 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" @@ -11,7 +19,6 @@ LF=' ' IFS="$LF" -rloga=fetch no_tags= tags= append= @@ -20,7 +27,8 @@ verbose= update_head_ok= exec= upload_pack= -keep=--thin +keep= +shallow_depth= while case "$#" in 0) break ;; esac do case "$1" in @@ -51,10 +59,14 @@ do verbose=Yes ;; -k|--k|--ke|--kee|--keep) - keep=--keep + keep='-k -k' ;; - --reflog-action=*) - rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'` + --depth=*) + shallow_depth="--depth=`expr "z$1" : 'z-[^=]*=\(.*\)'`" + ;; + --depth) + shift + shallow_depth="--depth=$1" ;; -*) usage @@ -80,14 +92,15 @@ refs= rref= rsync_slurped_objects= -rloga="$rloga $remote_nick" -test "$remote_nick" = "$remote" || rloga="$rloga $remote" - if test "" = "$append" then : >"$GIT_DIR/FETCH_HEAD" fi +# Global that is reused later +ls_remote_result=$(git ls-remote $upload_pack "$remote") || + die "Cannot get the repository state from $remote" + append_fetch_head () { head_="$1" remote_="$2" @@ -147,27 +160,27 @@ update_local_ref () { [ "$verbose" ] && echo >&2 " $label_: $newshort_" return 0 fi - oldshort_=$(git-rev-parse --short "$1" 2>/dev/null) - mkdir -p "$(dirname "$GIT_DIR/$1")" + oldshort_=$(git show-ref --hash --abbrev "$1" 2>/dev/null) + case "$1" in refs/tags/*) # Tags need not be pointing at commits so there # is no way to guarantee "fast-forward" anyway. - if test -f "$GIT_DIR/$1" + if test -n "$oldshort_" then - if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2" + if now_=$(git show-ref --hash "$1") && test "$now_" = "$2" then [ "$verbose" ] && echo >&2 "* $1: same as $3" [ "$verbose" ] && echo >&2 " $label_: $newshort_" ||: else echo >&2 "* $1: updating with $3" echo >&2 " $label_: $newshort_" - git-update-ref -m "$rloga: updating tag" "$1" "$2" + git-update-ref -m "$GIT_REFLOG_ACTION: updating tag" "$1" "$2" fi else echo >&2 "* $1: storing $3" echo >&2 " $label_: $newshort_" - git-update-ref -m "$rloga: storing tag" "$1" "$2" + git-update-ref -m "$GIT_REFLOG_ACTION: storing tag" "$1" "$2" fi ;; @@ -190,7 +203,7 @@ update_local_ref () { *,$local) echo >&2 "* $1: fast forward to $3" echo >&2 " old..new: $oldshort_..$newshort_" - git-update-ref -m "$rloga: fast-forward" "$1" "$2" "$local" + git-update-ref -m "$GIT_REFLOG_ACTION: fast-forward" "$1" "$2" "$local" ;; *) false @@ -200,7 +213,7 @@ update_local_ref () { *,t,*) echo >&2 "* $1: forcing update to non-fast forward $3" echo >&2 " old...new: $oldshort_...$newshort_" - git-update-ref -m "$rloga: forced-update" "$1" "$2" "$local" + git-update-ref -m "$GIT_REFLOG_ACTION: forced-update" "$1" "$2" "$local" ;; *) echo >&2 "* $1: not updating to non-fast forward $3" @@ -212,7 +225,7 @@ update_local_ref () { else echo >&2 "* $1: storing $3" echo >&2 " $label_: $newshort_" - git-update-ref -m "$rloga: storing head" "$1" "$2" + git-update-ref -m "$GIT_REFLOG_ACTION: storing head" "$1" "$2" fi ;; esac @@ -232,11 +245,8 @@ esac reflist=$(get_remote_refs_for_fetch "$@") if test "$tags" then - taglist=`IFS=" " && - ( - git-ls-remote $upload_pack --tags "$remote" || - echo fail ouch - ) | + taglist=`IFS=' ' && + echo "$ls_remote_result" | while read sha1 name do case "$sha1" in @@ -245,6 +255,8 @@ then esac case "$name" in *^*) continue ;; + refs/tags/*) ;; + *) continue ;; esac if git-check-ref-format "$name" then @@ -296,6 +308,9 @@ fetch_main () { # There are transports that can fetch only one head at a time... case "$remote" in http://* | https://* | ftp://*) + test -n "$shallow_depth" && + die "shallow clone with http not supported" + proto=`expr "$remote" : '\([^:]*\):'` if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi @@ -303,26 +318,26 @@ fetch_main () { "`git-repo-config --bool http.noEPSV`" = true ]; then noepsv_opt="--disable-epsv" fi - max_depth=5 - depth=0 - head="ref: $remote_name" - while (expr "z$head" : "zref:" && expr $depth \< $max_depth) >/dev/null - do - remote_name_quoted=$(@@PERL@@ -e ' - my $u = $ARGV[0]; - $u =~ s/^ref:\s*//; - $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg; - print "$u"; - ' "$head") - head=$(curl -nsfL $curl_extra_args $noepsv_opt "$remote/$remote_name_quoted") - depth=$( expr \( $depth + 1 \) ) - done + + # Find $remote_name from ls-remote output. + head=$( + IFS=' ' + echo "$ls_remote_result" | + while read sha1 name + do + test "z$name" = "z$remote_name" || continue + echo "$sha1" + break + done + ) expr "z$head" : "z$_x40\$" >/dev/null || - die "Failed to fetch $remote_name from $remote" - echo >&2 Fetching "$remote_name from $remote" using http + die "No such ref $remote_name at $remote" + echo >&2 "Fetching $remote_name from $remote using $proto" git-http-fetch -v -a "$head" "$remote/" || exit ;; rsync://*) + test -n "$shallow_depth" && + die "shallow clone with rsync not supported" TMP_HEAD="$GIT_DIR/TMP_HEAD" rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1 head=$(git-rev-parse --verify TMP_HEAD) @@ -358,7 +373,7 @@ fetch_main () { esac append_fetch_head "$head" "$remote" \ - "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" + "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit done @@ -367,9 +382,10 @@ fetch_main () { ;; # we are already done. *) ( : subshell because we muck with IFS + pack_lockfile= IFS=" $LF" ( - git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote" + git-fetch-pack --thin $exec $keep $shallow_depth "$remote" $rref || echo failed "$remote" ) | while read sha1 remote_name do @@ -377,6 +393,12 @@ fetch_main () { failed) echo >&2 "Fetch failure: $remote" exit 1 ;; + # special line coming from index-pack with the pack name + pack) + continue ;; + keep) + pack_lockfile="$GIT_OBJECT_DIRECTORY/pack/pack-$remote_name.keep" + continue ;; esac found= single_force= @@ -405,14 +427,16 @@ fetch_main () { done local_name=$(expr "z$found" : 'z[^:]*:\(.*\)') append_fetch_head "$sha1" "$remote" \ - "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" - done + "$remote_name" "$remote_nick" "$local_name" \ + "$not_for_merge" || exit + done && + if [ "$pack_lockfile" ]; then rm -f "$pack_lockfile"; fi ) || exit ;; esac } -fetch_main "$reflist" +fetch_main "$reflist" || exit # automated tag following case "$no_tags$tags" in @@ -421,16 +445,11 @@ case "$no_tags$tags" in *:refs/*) # effective only when we are following remote branch # using local tracking branch. - taglist=$(IFS=" " && - git-ls-remote $upload_pack --tags "$remote" | - sed -ne 's|^\([0-9a-f]*\)[ ]\(refs/tags/.*\)^{}$|\1 \2|p' | + taglist=$(IFS=' ' && + echo "$ls_remote_result" | + git-show-ref --exclude-existing=refs/tags/ | while read sha1 name do - test -f "$GIT_DIR/$name" && continue - git-check-ref-format "$name" || { - echo >&2 "warning: tag ${name} ignored" - continue - } git-cat-file -t "$sha1" >/dev/null 2>&1 || continue echo >&2 "Auto-following $name" echo ".${name}:${name}" @@ -439,7 +458,9 @@ case "$no_tags$tags" in case "$taglist" in '') ;; ?*) - fetch_main "$taglist" ;; + # do not deepen a shallow tree when following tags + shallow_depth= + fetch_main "$taglist" || exit ;; esac esac @@ -453,7 +474,7 @@ case "$orig_head" in if test "$curr_head" != "$orig_head" then git-update-ref \ - -m "$rloga: Undoing incorrectly fetched HEAD." \ + -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \ HEAD "$orig_head" die "Cannot fetch into the current branch." fi