#!/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] [-q] [-u ] " 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|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 } # 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 # 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"