# Clone a repository into a different directory that does not yet exist.
usage() {
- echo >&2 "* git clone [-l] <repo> <dir>"
+ echo >&2 "* git clone [-l] [-q] [-u <upload-pack>] <repo> <dir>"
exit 1
}
+get_repo_base() {
+ (cd "$1" && (cd .git ; pwd)) 2> /dev/null
+}
+
+quiet=
use_local=no
+upload_pack=
while
case "$#,$1" in
0,*) break ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
+ *,-q|*,--quiet) quiet=-q ;;
+ 1,-u|*,--upload-pack) usage ;;
+ *,-u|*,--upload-pack)
+ shift
+ upload_pack="--exec=$2" ;;
*,-*) usage ;;
*) break ;;
esac
shift
done
+# Turn the source into an absolute path if
+# it is local
repo="$1"
+local=no
+if base=$(get_repo_base "$repo"); then
+ repo="$base"
+ local=yes
+fi
+
dir="$2"
mkdir "$dir" &&
D=$(
test -d "$D" || usage
# We do local magic only when the user tells us to.
-case "$use_local" in
-yes)
+case "$local,$use_local" in
+yes,yes)
( cd "$repo/objects" ) || {
- repo="$repo/.git"
- ( cd "$repo/objects" ) || {
- echo >&2 "-l flag seen but $repo is not local."
- exit 1
- }
+ echo >&2 "-l flag seen but $repo is not local."
+ exit 1
}
# See if we can hardlink and drop "l" if not.
l=l
fi &&
rm -f "$D/.git/objects/sample" &&
- cp -r$l "$repo/objects" "$D/.git/" || exit 1
+ cd "$repo" &&
+ find objects -type f -print |
+ cpio -puamd$l "$D/.git/" || exit 1
# Make a duplicate of refs and HEAD pointer
HEAD=
;;
esac
-cd "$D" && git clone-pack "$repo"
+case "$repo" in
+rsync://*)
+ rsync $quiet -avz --ignore-existing "$repo/objects/" "$D/.git/objects/" &&
+ rsync $quiet -avz --ignore-existing "$repo/refs/" "$D/.git/refs/"
+ ;;
+http://*)
+ echo "Somebody should add http fetch" >&2
+ exit 1
+ ;;
+*)
+ cd "$D" && case "$upload_pack" in
+ '') git-clone-pack $quiet "$repo" ;;
+ *) git-clone-pack $quiet "$upload_pack" "$repo" ;;
+ esac
+ ;;
+esac