101 lines
2.6 KiB
Plaintext
101 lines
2.6 KiB
Plaintext
|
#!/bin/sh
|
||
|
#
|
||
|
# Copyright (c) 2005, Junio C Hamano
|
||
|
#
|
||
|
# Called by git-fetch-script
|
||
|
# Exits 2 when the remote site does not support dumb server protocol.
|
||
|
|
||
|
# Usage: git-fetch-dumb-http <head-SHA1> <repo> [ <head> | tag <tag> ]
|
||
|
|
||
|
. git-sh-setup-script || die "Not a git archive"
|
||
|
head="$1"
|
||
|
shift
|
||
|
. git-parse-remote "$@"
|
||
|
|
||
|
merge_repo="$_remote_repo"
|
||
|
merge_head="$_remote_head"
|
||
|
merge_store="$_remote_store"
|
||
|
|
||
|
if [ -n "$GIT_SSL_NO_VERIFY" ]; then
|
||
|
curl_extra_args="-k"
|
||
|
fi
|
||
|
http_fetch () {
|
||
|
# $1 = Remote, $2 = Local
|
||
|
curl -ns $curl_extra_args "$1" >"$2"
|
||
|
}
|
||
|
|
||
|
# Try dumb server protocol
|
||
|
|
||
|
clone_tmp=".git/clone-tmp$$" &&
|
||
|
mkdir -p "$clone_tmp" || exit 1
|
||
|
trap "rm -rf $clone_tmp" 0 1 2 3 15
|
||
|
http_fetch "$merge_repo/info/refs" "$clone_tmp/refs" &&
|
||
|
http_fetch "$merge_repo/objects/info/packs" "$clone_tmp/packs" &&
|
||
|
http_fetch "$merge_repo/info/rev-cache" "$clone_tmp/rev-cache" || exit 2
|
||
|
|
||
|
# Which packs are we interested in?
|
||
|
has_missing=,
|
||
|
while read tag num sha1 type
|
||
|
do
|
||
|
case "$tag" in
|
||
|
T) ;;
|
||
|
*) continue ;;
|
||
|
esac
|
||
|
git-cat-file -t "$sha1" >/dev/null || has_missing="$has_missing$num,"
|
||
|
done <$clone_tmp/packs
|
||
|
|
||
|
# Slurp the pack index we do not have all objects for.
|
||
|
pack_ix=0
|
||
|
may_want_pack_count=0
|
||
|
while read tag pack
|
||
|
do
|
||
|
case "$tag" in
|
||
|
P) ;;
|
||
|
*) break ;; # P records always come first.
|
||
|
esac
|
||
|
case "$has_missing" in
|
||
|
*",$pack_ix,"*)
|
||
|
name=`expr "$pack" : '\(.*\)\.pack$'` &&
|
||
|
idx="$name.idx" &&
|
||
|
http_fetch "$merge_repo/objects/pack/$idx" "$clone_tmp/$idx" &&
|
||
|
# Note that idx file is sorted --- otherwise we need to sort it here.
|
||
|
git-show-index <"$clone_tmp/$idx" |
|
||
|
sed -e 's/^[^ ]* //' >"$clone_tmp/$name.toc" ||
|
||
|
exit 1
|
||
|
may_want_pack_count=`expr "$may_want_pack_count" + 1`
|
||
|
;;
|
||
|
esac
|
||
|
pack_ix=`expr "$pack_ix" + 1`
|
||
|
done <$clone_tmp/packs
|
||
|
|
||
|
case "$may_want_pack_count" in
|
||
|
0)
|
||
|
exit 0 ;;
|
||
|
esac
|
||
|
|
||
|
# We want $head. What are the head objects we are missing?
|
||
|
git-missing-revs $clone_tmp/rev-cache $head >$clone_tmp/missing-revs &&
|
||
|
sort -o $clone_tmp/missing-revs $clone_tmp/missing-revs || exit 2
|
||
|
|
||
|
for toc in $clone_tmp/*.toc
|
||
|
do
|
||
|
name=`expr $toc : '.*/\([^/]*\)\.toc'` &&
|
||
|
comm -12 $clone_tmp/missing-revs $toc >$clone_tmp/$name.can
|
||
|
# FIXME: this is stupid.
|
||
|
if test -s $clone_tmp/$name.can
|
||
|
then
|
||
|
pack="$name.pack" idx="$name.idx" &&
|
||
|
http_fetch "$merge_repo/objects/pack/$pack" "$clone_tmp/$pack" &&
|
||
|
git-verify-pack "$clone_tmp/$pack" &&
|
||
|
mkdir -p "$GIT_OBJECT_DIRECTORY/pack" &&
|
||
|
mv "$clone_tmp/$pack" "$clone_tmp/$idx" \
|
||
|
"$GIT_OBJECT_DIRECTORY/pack/" || {
|
||
|
# remote may just have a stale dumb server information files.
|
||
|
# and normal pull might succeed.
|
||
|
exit 2
|
||
|
}
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
exit 0
|