#!/usr/bin/env bash # # Clone a remote GIT repository. # Copyright (c) Petr Baudis, 2005 # # This clones a remote GIT repository and checks it out locally. # # Takes a parameter specifying the location of the source repository and an # optional second parameter specifying the destination. If the second # parameter is omitted, the basename of the source repository is used as the # destination. # # For detailed description of the location of the source repository format # (available protocols, specifying different remote branch, etc) please see # the `cg-branch-add` documentation. # # OPTIONS # ------- # -l:: Symlink the object database when cloning locally # Symlink the object database when cloning locally, instead of # hardlinking all the objects. This is suitable for very fast # cloning of arbitrarily big repositories, but might be a trouble # in multi-user environments, and less solid arrangement in case # you do dangerous things with the database. Also, disappeared # or moved origin repository will obviously render this one unusable # as well. The choice is yours. # Note that you MUST NOT prune repository containing a symlink # or being symlinked to. # # -s:: Clone into the current directory # Clone in the current directory instead of creating a new one. # Specifying both -s and a destination directory makes no sense. # # NOTES # ----- # If the clone has been interrupted for any reason, do not panic, calmly # cd to the destination directory and run `cg-fetch`, which will in this case # restart the initial clone. Chances are that you will not actually download # any duplicate data. (At the time of writing this, the chances aren't for # the native git protocol and ssh, but this may change in the future). # # EXAMPLE USAGE # ------------- # If you want to clone the Cogito repository, you can say: # # $ cg-clone http://www.kernel.org/pub/scm/cogito/cogito.git # # and it will be cloned to the 'cogito' subdirectory of the current directory. # # To clone the 'next' branch of the Git repository, do e.g.: # # $ cg-clone git://git.kernel.org/pub/scm/git/git.git#next USAGE="cg-clone [-l] [-s] LOCATION [DESTDIR]" _git_repo_unneeded=1 . "${COGITO_LIB}"cg-Xlib || exit 1 same_dir= symlink= while optparse; do if optparse -l; then symlink=1 elif optparse -s; then same_dir=1 else optfail fi done location="${ARGS[0]}" [ -n "$location" ] || usage location="${location%/}" destdir="${ARGS[1]}" if [ "$destdir" ]; then [ ! "$same_dir" ] || die "specifying both -s and DESTDIR makes no sense" dir="$destdir" else dir="${location%#*}"; dir="${dir%/.git}"; dir="${dir##*/}"; dir="${dir%.git}" fi if ! echo "$location" | grep -q ":" ; then location=$(echo "$location" | sed -e "s#^[^/]#$(pwd)\/&#") else [ ! "$symlink" ] || die "specifying -l for non-local clone makes no sense" location="$location" fi if [ ! "$same_dir" ]; then [ -e "$dir" ] && die "$dir/ already exists" mkdir -p "$dir" || exit $? cd "$dir" || exit $? else dir=. fi cleanup () { if [ -s "$_git/info/cg-fetch-earlydie" ] && [ ! "$same_dir" ]; then cd .. rm -rf "$dir" fi } cleanup_trap "cleanup" cg-init -I || die "init failed" if [ "$symlink" ]; then rmdir "$_git/objects/"* rmdir "$_git/objects" src="${location%#*}" [ -d "$src/.git" ] && src="$src/.git" ln -s "$src/objects" "$_git/objects" fi cg-branch-add origin "$location" echo $$ >"$_git/info/cg-fetch-initial" echo $$ >"$_git/info/cg-fetch-earlydie" cat >___ <<__EOT__ This is a clone-in-progress GIT working tree containing a GIT repository in the .git subdirectory. If you see this file and noone is fetching or cloning in this repository, the clone has been interrupted; you can restart it by issuing this command (it's enough as-is): cg-fetch __EOT__ cg-fetch origin || { cleanup; exit 1; } echo "Cloned to $dir/ (origin $location available as branch \"origin\")"