You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

159 lines
3.7 KiB

#!/bin/sh
#
. git-sh-setup-script || die "Not a git archive"
. git-parse-remote-script
_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=
case "$#" in
0)
die "Where do you want to fetch from?" ;;
*)
case "$1" in
-a|--a|--ap|--app|--appe|--appen|--append)
append=t
shift ;;
esac
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"
# 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
head_=$(git-rev-parse --verify "$head_^0") || exit
note_="$head_ $remote_name_ from $remote_nick_"
echo "$note_" >>$GIT_DIR/FETCH_HEAD
echo >&2 "* committish: $note_"
else
echo >&2 "* non-commit: $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_" "$remote_" "$remote_name_"
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.
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 $4"
echo >&2 " from $3"
;;
*,$local)
echo >&2 "* $1: fast forward to $4"
echo >&2 " from $3"
;;
*)
false
;;
esac || {
mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
echo >&2 "* $1: does not fast forward to $4"
echo >&2 " from $3; leaving it in '$1.remote'"
}
else
echo >&2 "* $1: storing $4"
echo >&2 " from $3."
fi
test -f "$GIT_DIR/$1.lock" &&
mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
;;
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
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-pull -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=
for ref in $refs
do
case "$ref" in
$remote_name:*)
found="$ref"
break ;;
esac
done
local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
done
;;
esac