aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgit-clone.sh28
-rwxr-xr-xgit-fetch.sh24
-rwxr-xr-xgit-parse-remote.sh21
3 files changed, 68 insertions, 5 deletions
diff --git a/git-clone.sh b/git-clone.sh
index a21f13af2..bfb8fd628 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -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"
diff --git a/git-fetch.sh b/git-fetch.sh
index 227394403..72f17ab6c 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -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
}
;;
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 3c5d94b34..a9db0cd82 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -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
+}