Teach rsync transport about alternates.

For local operations and downloading and uploading via git aware protocols,
use of $GIT_OBJECT_DIRECTORY/info/alternates is recommended on the server
side for big projects that are derived from another one (like Linux kernel).

However, dumb protocols and rsync transport needs to resolve this on the
client end, which we did not bother doing until this week.

I noticed we use "rsync -z" but most of our payload is already compressed,
which was not quite right.  This commit also fixes it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2005-09-17 11:56:41 -07:00
Родитель 8805ccac40
Коммит 4447badcd2
3 изменённых файлов: 68 добавлений и 5 удалений

Просмотреть файл

@ -144,8 +144,32 @@ yes,yes)
*)
case "$repo" in
rsync://*)
rsync $quiet -avz --ignore-existing "$repo/objects/" "$D/.git/objects/" &&
rsync $quiet -avz --ignore-existing "$repo/refs/" "$D/.git/refs/"
rsync $quiet -av --ignore-existing \
--exclude info "$repo/objects/" "$D/.git/objects/" &&
rsync $quiet -av --ignore-existing \
--exclude info "$repo/refs/" "$D/.git/refs/" || exit
# Look at objects/info/alternates for rsync -- http will
# support it natively and git native ones will do it on the
# remote end. Not having that file is not a crime.
rsync -q "$repo/objects/info/alternates" "$D/.git/TMP_ALT" ||
rm -f "$D/.git/TMP_ALT"
if test -f "$D/.git/TMP_ALT"
then
( cd $D &&
. git-parse-remote &&
resolve_alternates "$repo" <"./.git/TMP_ALT" ) |
while read alt
do
case "$alt" in 'bad alternate: '*) die "$alt";; esac
case "$quiet" in
'') echo >&2 "Getting alternate: $alt" ;;
esac
rsync $quiet -av --ignore-existing \
--exclude info "$alt" "$D/.git/objects" || exit
done
rm -f "$D/.git/TMP_ALT"
fi
;;
http://*)
clone_dumb_http "$repo" "$D"

Просмотреть файл

@ -183,12 +183,30 @@ do
;;
rsync://*)
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
rsync -L -q "$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 -av --ignore-existing --exclude info \
"$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
# Look at objects/info/alternates for rsync -- http will
# support it natively and git native ones will do it on the remote
# end. Not having that file is not a crime.
rsync -q "$remote/objects/info/alternates" "$GIT_DIR/TMP_ALT" ||
rm -f "$GIT_DIR/TMP_ALT"
if test -f "$GIT_DIR/TMP_ALT"
then
resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
while read alt
do
case "$alt" in 'bad alternate: '*) die "$alt";; esac
echo >&2 "Getting alternate: $alt"
rsync -av --ignore-existing --exclude info \
"$alt" "$GIT_OBJECT_DIRECTORY/" || exit
done
rm -f "$GIT_DIR/TMP_ALT"
fi
rsync_slurped_objects=t
}
;;

Просмотреть файл

@ -153,3 +153,24 @@ get_remote_refs_for_fetch () {
;;
esac
}
resolve_alternates () {
# original URL (xxx.git)
top_=`expr "$1" : '\([^:]*:/*[^/]*\)/'`
while read path
do
case "$path" in
\#* | '')
continue ;;
/*)
echo "$top_$path/" ;;
../*)
# relative -- ugly but seems to work.
echo "$1/objects/$path/" ;;
*)
# exit code may not be caught by the reader.
echo "bad alternate: $path"
exit 1 ;;
esac
done
}