X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-fetch.sh;h=fd70696b7479ad08eedbb44b75654f07247cc37b;hb=957d6ea78fcbe71481a6f46a58768e100f7908e0;hp=38101a6ace2331707bb7a424d32b32f3699d3bab;hpb=00bc0ec26296aad8727dcc75f031c7b11e404f20;p=git.git diff --git a/git-fetch.sh b/git-fetch.sh index 38101a6ac..fd70696b7 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -4,11 +4,9 @@ USAGE=' ...' SUBDIRECTORY_OK=Yes . git-sh-setup -TOP=$(git-rev-parse --show-cdup) -if test ! -z "$TOP" -then - cd "$TOP" -fi +set_reflog_action "fetch $*" +cd_to_toplevel ;# probably unnecessary... + . 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" @@ -17,7 +15,6 @@ LF=' ' IFS="$LF" -rloga=fetch no_tags= tags= append= @@ -25,8 +22,10 @@ force= verbose= update_head_ok= exec= -upload_pack= keep= +shallow_depth= +no_progress= +test -t 1 || no_progress=--no-progress while case "$#" in 0) break ;; esac do case "$1" in @@ -36,8 +35,12 @@ do --upl|--uplo|--uploa|--upload|--upload-|--upload-p|\ --upload-pa|--upload-pac|--upload-pack) shift - exec="--exec=$1" - upload_pack="-u $1" + exec="--upload-pack=$1" + ;; + --upl=*|--uplo=*|--uploa=*|--upload=*|\ + --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*) + exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') + shift ;; -f|--f|--fo|--for|--forc|--force) force=t @@ -59,8 +62,12 @@ do -k|--k|--ke|--kee|--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,158 +87,49 @@ case "$#" in set x $origin ; shift ;; esac +if test -z "$exec" +then + # No command line override and we have configuration for the remote. + exec="--upload-pack=$(get_uploadpack $1)" +fi + remote_nick="$1" remote=$(get_remote_url "$@") 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 find the reflist at $remote" +ls_remote_result=$(git ls-remote $exec "$remote") || + die "Cannot get the repository state from $remote" append_fetch_head () { - head_="$1" - remote_="$2" - remote_name_="$3" - remote_nick_="$4" - local_name_="$5" - case "$6" in - t) not_for_merge_='not-for-merge' ;; - '') not_for_merge_= ;; - esac - - # remote-nick is the URL given on the command line (or a shorthand) - # remote-name is the $GIT_DIR relative refs/ path we computed - # for this refspec. - - # the $note_ variable will be fed to git-fmt-merge-msg for further - # processing. - case "$remote_name_" in - HEAD) - note_= ;; - refs/heads/*) - note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')" - note_="branch '$note_' of " ;; - refs/tags/*) - note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')" - note_="tag '$note_' of " ;; - refs/remotes/*) - note_="$(expr "$remote_name_" : 'refs/remotes/\(.*\)')" - note_="remote branch '$note_' of " ;; - *) - note_="$remote_name of " ;; - esac - remote_1_=$(expr "z$remote_" : 'z\(.*\)\.git/*$') && - remote_="$remote_1_" - note_="$note_$remote_" - - # 2.6.11-tree tag would not be happy to be fed to resolve. - 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" - else - echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD" - fi - - update_local_ref "$local_name_" "$head_" "$note_" + flags= + test -n "$verbose" && flags="$flags$LF-v" + test -n "$force$single_force" && flags="$flags$LF-f" + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ + git-fetch--tool $flags append-fetch-head "$@" } -update_local_ref () { - # If we are storing the head locally make sure that it is - # a fast forward (aka "reverse push"). - - label_=$(git-cat-file -t $2) - newshort_=$(git-rev-parse --short $2) - if test -z "$1" ; then - [ "$verbose" ] && echo >&2 "* fetched $3" - [ "$verbose" ] && echo >&2 " $label_: $newshort_" - return 0 - fi - 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 -n "$oldshort_" - then - 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" - fi - else - echo >&2 "* $1: storing $3" - echo >&2 " $label_: $newshort_" - git-update-ref -m "$rloga: storing tag" "$1" "$2" - fi - ;; - - refs/heads/* | refs/remotes/*) - # $1 is the ref being updated. - # $2 is the new value for the ref. - local=$(git-rev-parse --verify "$1^0" 2>/dev/null) - if test "$local" - then - # Require fast-forward. - mb=$(git-merge-base "$local" "$2") && - case "$2,$mb" in - $local,*) - if test -n "$verbose" - then - echo >&2 "* $1: same as $3" - echo >&2 " $label_: $newshort_" - fi - ;; - *,$local) - echo >&2 "* $1: fast forward to $3" - echo >&2 " old..new: $oldshort_..$newshort_" - git-update-ref -m "$rloga: fast-forward" "$1" "$2" "$local" - ;; - *) - false - ;; - esac || { - case ",$force,$single_force," in - *,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" - ;; - *) - echo >&2 "* $1: not updating to non-fast forward $3" - echo >&2 " old...new: $oldshort_...$newshort_" - exit 1 - ;; - esac - } - else - echo >&2 "* $1: storing $3" - echo >&2 " $label_: $newshort_" - git-update-ref -m "$rloga: storing head" "$1" "$2" - fi - ;; - esac -} +# updating the current HEAD with git-fetch in a bare +# repository is always fine. +if test -z "$update_head_ok" && test $(is_bare_repository) = false +then + orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) +fi -case "$update_head_ok" in +# Allow --notags from remote.$1.tagopt +case "$tags$no_tags" in '') - orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) - ;; + case "$(git-config --get "remote.$1.tagopt")" in + --no-tags) + no_tags=t ;; + esac esac # If --tags (and later --heads or --all) is specified, then we are @@ -244,23 +142,10 @@ if test "$tags" then taglist=`IFS=' ' && echo "$ls_remote_result" | + git-show-ref --exclude-existing=refs/tags/ | while read sha1 name do - case "$sha1" in - fail) - exit 1 - esac - case "$name" in - *^*) continue ;; - refs/tags/*) ;; - *) continue ;; - esac - if git-check-ref-format "$name" - then - echo ".${name}:${name}" - else - echo >&2 "warning: tag ${name} ignored" - fi + echo ".${name}:${name}" done` || exit if test "$#" -gt 1 then @@ -272,7 +157,40 @@ then fi fi -fetch_main () { +fetch_all_at_once () { + + eval=$(echo "$1" | git-fetch--tool parse-reflist "-") + eval "$eval" + + ( : subshell because we muck with IFS + IFS=" $LF" + ( + if test "$remote" = . ; then + git-show-ref $rref || echo failed "$remote" + elif test -f "$remote" ; then + test -n "$shallow_depth" && + die "shallow clone with bundle is not supported" + git-bundle unbundle "$remote" $rref || + echo failed "$remote" + else + git-fetch-pack --thin $exec $keep $shallow_depth $no_progress \ + "$remote" $rref || + echo failed "$remote" + fi + ) | + ( + flags= + test -n "$verbose" && flags="$flags -v" + test -n "$force" && flags="$flags -f" + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ + git-fetch--tool $flags native-store \ + "$remote" "$remote_nick" "$refs" + ) + ) || exit + +} + +fetch_per_ref () { reflist="$1" refs= rref= @@ -305,12 +223,14 @@ 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 if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-repo-config --bool http.noEPSV`" = true ]; then + "`git-config --bool http.noEPSV`" = true ]; then noepsv_opt="--disable-epsv" fi @@ -328,9 +248,11 @@ fetch_main () { expr "z$head" : "z$_x40\$" >/dev/null || 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 + 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) @@ -360,9 +282,6 @@ fetch_main () { rsync_slurped_objects=t } ;; - *) - # We will do git native transport with just one call later. - continue ;; esac append_fetch_head "$head" "$remote" \ @@ -370,63 +289,17 @@ fetch_main () { done - case "$remote" in - http://* | https://* | ftp://* | rsync://* ) - ;; # we are already done. - *) - ( : subshell because we muck with IFS - pack_lockfile= - IFS=" $LF" - ( - git-fetch-pack --thin $exec $keep "$remote" $rref || echo failed "$remote" - ) | - while read sha1 remote_name - do - case "$sha1" in - 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= - for ref in $refs - do - case "$ref" in - +$remote_name:*) - single_force=t - not_for_merge= - found="$ref" - break ;; - .+$remote_name:*) - single_force=t - not_for_merge=t - found="$ref" - break ;; - .$remote_name:*) - not_for_merge=t - found="$ref" - break ;; - $remote_name:*) - not_for_merge= - found="$ref" - break ;; - esac - done - local_name=$(expr "z$found" : 'z[^:]*:\(.*\)') - append_fetch_head "$sha1" "$remote" \ - "$remote_name" "$remote_nick" "$local_name" \ - "$not_for_merge" || exit - done && - if [ "$pack_lockfile" ]; then rm -f "$pack_lockfile"; fi - ) || exit ;; - esac +} +fetch_main () { + case "$remote" in + http://* | https://* | ftp://* | rsync://* ) + fetch_per_ref "$@" + ;; + *) + fetch_all_at_once "$@" + ;; + esac } fetch_main "$reflist" || exit @@ -451,6 +324,8 @@ case "$no_tags$tags" in case "$taglist" in '') ;; ?*) + # do not deepen a shallow tree when following tags + shallow_depth= fetch_main "$taglist" || exit ;; esac esac @@ -465,7 +340,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