git-commit-vandalism/git-fetch.sh
Junio C Hamano 215a7ad1ef Big tool rename.
As promised, this is the "big tool rename" patch.  The primary differences
since 0.99.6 are:

  (1) git-*-script are no more.  The commands installed do not
      have any such suffix so users do not have to remember if
      something is implemented as a shell script or not.

  (2) Many command names with 'cache' in them are renamed with
      'index' if that is what they mean.

There are backward compatibility symblic links so that you and
Porcelains can keep using the old names, but the backward
compatibility support  is expected to be removed in the near
future.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-07 17:45:20 -07:00

245 lines
5.4 KiB
Bash
Executable File

#!/bin/sh
#
. git-sh-setup || die "Not a git archive"
. 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"
append=
force=
update_head_ok=
while case "$#" in 0) break ;; esac
do
case "$1" in
-a|--a|--ap|--app|--appe|--appen|--append)
append=t
;;
-f|--f|--fo|--for|--forc|--force)
force=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
;;
*)
break
;;
esac
shift
done
case "$#" in
0)
test -f "$GIT_DIR/branches/origin" ||
test -f "$GIT_DIR/remotes/origin" ||
die "Where do you want to fetch from today?"
set origin ;;
esac
remote_nick="$1"
remote=$(get_remote_url "$@")
refs=
rref=
rsync_slurped_objects=
if test "" = "$append"
then
: >$GIT_DIR/FETCH_HEAD
fi
append_fetch_head () {
head_="$1"
remote_="$2"
remote_name_="$3"
remote_nick_="$4"
local_name_="$5"
# 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.
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 " ;;
*)
note_="$remote_name of " ;;
esac
remote_1_=$(expr "$remote_" : '\(.*\)\.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_ $note_" >>$GIT_DIR/FETCH_HEAD
echo >&2 "* committish: $head_"
echo >&2 " $note_"
else
echo >&2 "* non-commit: $head_"
echo >&2 " $note_"
fi
if test "$local_name_" != ""
then
# We are storing the head locally. Make sure that it is
# a fast forward (aka "reverse push").
fast_forward_local "$local_name_" "$head_" "$note_"
fi
}
fast_forward_local () {
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"
then
echo >&2 "* $1: updating with $3"
else
echo >&2 "* $1: storing $3"
fi
echo "$2" >"$GIT_DIR/$1" ;;
refs/heads/*)
# NEEDSWORK: use the same cmpxchg protocol here.
echo "$2" >"$GIT_DIR/$1.lock"
if test -f "$GIT_DIR/$1"
then
local=$(git-rev-parse --verify "$1^0") &&
mb=$(git-merge-base "$local" "$2") &&
case "$2,$mb" in
$local,*)
echo >&2 "* $1: same as $3"
;;
*,$local)
echo >&2 "* $1: fast forward to $3"
;;
*)
false
;;
esac || {
echo >&2 "* $1: does not fast forward to $3;"
case "$force,$single_force" in
t,* | *,t)
echo >&2 " forcing update."
;;
*)
mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
echo >&2 " leaving it in '$1.remote'"
;;
esac
}
else
echo >&2 "* $1: storing $3"
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)
;;
esac
for ref in $(get_remote_refs_for_fetch "$@")
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
single_force=t
ref=$(expr "$ref" : '\+\(.*\)')
else
single_force=
fi
remote_name=$(expr "$ref" : '\([^:]*\):')
local_name=$(expr "$ref" : '[^:]*:\(.*\)')
rref="$rref $remote_name"
# There are transports that can fetch only one head at a time...
case "$remote" in
http://* | https://*)
if [ -n "$GIT_SSL_NO_VERIFY" ]; then
curl_extra_args="-k"
fi
head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
expr "$head" : "$_x40\$" >/dev/null ||
die "Failed to fetch $remote_name from $remote"
echo Fetching "$remote_name from $remote" using http
git-http-fetch -v -a "$head" "$remote/" || exit
;;
rsync://*)
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
head=$(git-rev-parse TMP_HEAD)
rm -f "$TMP_HEAD"
test "$rsync_slurped_objects" || {
rsync -avz --ignore-existing "$remote/objects/" \
"$GIT_OBJECT_DIRECTORY/" || exit
rsync_slurped_objects=t
}
;;
*)
# We will do git native transport with just one call later.
continue ;;
esac
append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
done
case "$remote" in
http://* | https://* | rsync://* )
;; # we are already done.
*)
git-fetch-pack "$remote" $rref |
while read sha1 remote_name
do
found=
single_force=
for ref in $refs
do
case "$ref" in
+$remote_name:*)
single_force=t
found="$ref"
break ;;
$remote_name:*)
found="$ref"
break ;;
esac
done
local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
done
;;
esac
# If the original head was empty (i.e. no "master" yet), or
# if we were told not to worry, we do not have to check.
case ",$update_head_ok,$orig_head," in
*,, | t,* )
;;
*)
curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
if test "$curr_head" != "$orig_head"
then
echo "$orig_head" >$GIT_DIR/HEAD
die "Cannot fetch into the current branch."
fi
;;
esac