aae4f42c45
Using the $GIT_OBJECT_DIRECTORY/info/alternates mechanism, create a new repository that borrows objects from the original repository when --shared flag is given in addition to --local. It is worth pointing out that the "cloned" repository depends on the original repository, so this should be used only when you can reasonably trust that the original repository would not disappear without your knowing. Signed-off-by: Junio C Hamano <junkio@cox.net>
129 lines
2.6 KiB
Bash
Executable File
129 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Copyright (c) 2005, Linus Torvalds
|
|
# Copyright (c) 2005, Junio C Hamano
|
|
#
|
|
# Clone a repository into a different directory that does not yet exist.
|
|
|
|
usage() {
|
|
echo >&2 "* git clone [-l [-s]] [-q] [-u <upload-pack>] <repo> <dir>"
|
|
exit 1
|
|
}
|
|
|
|
get_repo_base() {
|
|
(cd "$1" && (cd .git ; pwd)) 2> /dev/null
|
|
}
|
|
|
|
quiet=
|
|
use_local=no
|
|
local_shared=no
|
|
upload_pack=
|
|
while
|
|
case "$#,$1" in
|
|
0,*) break ;;
|
|
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
|
|
*,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
|
|
local_shared=yes ;;
|
|
*,-q|*,--quiet) quiet=-q ;;
|
|
1,-u|1,--upload-pack) usage ;;
|
|
*,-u|*,--upload-pack)
|
|
shift
|
|
upload_pack="--exec=$1" ;;
|
|
*,-*) usage ;;
|
|
*) break ;;
|
|
esac
|
|
do
|
|
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=$(
|
|
(cd "$dir" && git-init-db && pwd)
|
|
) &&
|
|
test -d "$D" || usage
|
|
|
|
# We do local magic only when the user tells us to.
|
|
case "$local,$use_local" in
|
|
yes,yes)
|
|
( cd "$repo/objects" ) || {
|
|
echo >&2 "-l flag seen but $repo is not local."
|
|
exit 1
|
|
}
|
|
|
|
case "$local_shared" in
|
|
no)
|
|
# See if we can hardlink and drop "l" if not.
|
|
sample_file=$(cd "$repo" && \
|
|
find objects -type f -print | sed -e 1q)
|
|
|
|
# objects directory should not be empty since we are cloning!
|
|
test -f "$repo/$sample_file" || exit
|
|
|
|
l=
|
|
if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null
|
|
then
|
|
l=l
|
|
fi &&
|
|
rm -f "$D/.git/objects/sample" &&
|
|
cd "$repo" &&
|
|
find objects -type f -print |
|
|
cpio -puamd$l "$D/.git/" || exit 1
|
|
;;
|
|
yes)
|
|
mkdir -p "$D/.git/objects/info"
|
|
echo "$repo/objects" >"$D/.git/objects/info/alternates"
|
|
;;
|
|
esac
|
|
|
|
# Make a duplicate of refs and HEAD pointer
|
|
HEAD=
|
|
if test -f "$repo/HEAD"
|
|
then
|
|
HEAD=HEAD
|
|
fi
|
|
tar Ccf "$repo" - refs $HEAD | tar Cxf "$D/.git" - || exit 1
|
|
;;
|
|
*)
|
|
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://*)
|
|
git-clone-dumb-http "$repo" "$D"
|
|
case "$?" in
|
|
2)
|
|
echo "Somebody should define smarter http server protocol" >&2
|
|
exit 1
|
|
;;
|
|
0)
|
|
;;
|
|
*)
|
|
exit
|
|
esac
|
|
;;
|
|
*)
|
|
cd "$D" && case "$upload_pack" in
|
|
'') git-clone-pack $quiet "$repo" ;;
|
|
*) git-clone-pack $quiet "$upload_pack" "$repo" ;;
|
|
esac
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
# Update origin.
|
|
mkdir -p "$D/.git/branches/" &&
|
|
rm -f "$D/.git/branches/origin" &&
|
|
echo "$repo" >"$D/.git/branches/origin"
|