X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=git-fetch.sh;h=61da6a9e3167845cf5b0f9260206b2dd590532df;hb=df8baa42fe4eeb5a021ac262caf601f44d2a5746;hp=e4a6a68057edf0ff8cd4067f334ddf1eed211e44;hpb=0b7a9fc971712308712fedbba404f7b448e37d45;p=git.git diff --git a/git-fetch.sh b/git-fetch.sh index e4a6a680..61da6a9e 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -5,6 +5,7 @@ _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" +tags= append= force= update_head_ok= @@ -17,6 +18,9 @@ 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) @@ -54,6 +58,10 @@ append_fetch_head () { 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 @@ -78,10 +86,11 @@ append_fetch_head () { if git-cat-file commit "$head_" >/dev/null 2>&1 then headc_=$(git-rev-parse --verify "$head_^0") || exit - echo "$headc_ $note_" >>$GIT_DIR/FETCH_HEAD + echo "$headc_ $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD echo >&2 "* committish: $head_" echo >&2 " $note_" else + echo "$head_ not-for-merge $note_" >>$GIT_DIR/FETCH_HEAD echo >&2 "* non-commit: $head_" echo >&2 " $note_" fi @@ -105,14 +114,16 @@ fast_forward_local () { else echo >&2 "* $1: storing $3" fi - echo "$2" >"$GIT_DIR/$1" ;; + git-update-ref "$1" "$2" + ;; refs/heads/*) - # NEEDSWORK: use the same cmpxchg protocol here. - echo "$2" >"$GIT_DIR/$1.lock" - if test -f "$GIT_DIR/$1" + # $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 - local=$(git-rev-parse --verify "$1^0") && + # Require fast-forward. mb=$(git-merge-base "$local" "$2") && case "$2,$mb" in $local,*) @@ -120,43 +131,69 @@ fast_forward_local () { ;; *,$local) echo >&2 "* $1: fast forward to $3" + git-update-ref "$1" "$2" "$local" ;; *) false ;; esac || { echo >&2 "* $1: does not fast forward to $3;" - case "$force,$single_force" in - t,* | *,t) + case ",$force,$single_force," in + *,t,*) echo >&2 " forcing update." + git-update-ref "$1" "$2" "$local" ;; *) - mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote" - echo >&2 " leaving it in '$1.remote'" + echo >&2 " not updating." ;; esac } else - echo >&2 "* $1: storing $3" + echo >&2 "* $1: storing $3" + git-update-ref "$1" "$2" fi - test -f "$GIT_DIR/$1.lock" && - mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1" ;; esac } case "$update_head_ok" in '') - orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null) + orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) ;; 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" | awk '{ print "."$2":"$2 }') + if test "$#" -gt 1 + then + # remote URL plus explicit refspecs; we need to merge them. + reflist="$reflist $taglist" + else + # No explicit refspecs; fetch tags only. + reflist=$taglist + fi +fi + +for ref in $reflist do refs="$refs $ref" # These are relative path from $GIT_DIR, typically starting at refs/ # but may be HEAD + if expr "$ref" : '\.' >/dev/null + then + not_for_merge=t + ref=$(expr "$ref" : '\.\(.*\)') + else + not_for_merge= + fi if expr "$ref" : '\+' >/dev/null then single_force=t @@ -184,7 +221,7 @@ do rsync://*) TMP_HEAD="$GIT_DIR/TMP_HEAD" rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1 - head=$(git-rev-parse TMP_HEAD) + head=$(git-rev-parse --verify TMP_HEAD) rm -f "$TMP_HEAD" test "$rsync_slurped_objects" || { rsync -av --ignore-existing --exclude info \ @@ -216,7 +253,8 @@ do continue ;; esac - append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name" + append_fetch_head "$head" "$remote" \ + "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" done @@ -241,16 +279,27 @@ http://* | https://* | rsync://* ) 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 "$found" : '[^:]*:\(.*\)') - append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name" + append_fetch_head "$sha1" "$remote" \ + "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" done || exit ;; esac @@ -261,10 +310,10 @@ case ",$update_head_ok,$orig_head," in *,, | t,* ) ;; *) - curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null) + curr_head=$(git-rev-parse --verify HEAD 2>/dev/null) if test "$curr_head" != "$orig_head" then - echo "$orig_head" >$GIT_DIR/HEAD + git-update-ref HEAD "$orig_head" die "Cannot fetch into the current branch." fi ;;