1#!/bin/sh 2 3usage () { 4echo"usage:" $@ 5exit127 6} 7 8die () { 9echo $@ 10exit128 11} 12 13failed () { 14 die "unable to create new workdir '$new_workdir'!" 15} 16 17iftest$#-lt2||test$#-gt3 18then 19 usage "$0<repository> <new_workdir> [<branch>]" 20fi 21 22orig_git=$1 23new_workdir=$2 24branch=$3 25 26# want to make sure that what is pointed to has a .git directory ... 27git_dir=$(cd"$orig_git"2>/dev/null && 28 git rev-parse --git-dir2>/dev/null) || 29 die "Not a git repository:\"$orig_git\"" 30 31case"$git_dir"in 32.git) 33 git_dir="$orig_git/.git" 34;; 35.) 36 git_dir=$orig_git 37;; 38esac 39 40# don't link to a configured bare repository 41isbare=$(git --git-dir="$git_dir" config --bool --get core.bare) 42iftest ztrue ="z$isbare" 43then 44 die "\"$git_dir\"has core.bare set to true," \ 45" remove from\"$git_dir/config\"to use$0" 46fi 47 48# don't link to a workdir 49iftest -h"$git_dir/config" 50then 51 die "\"$orig_git\"is a working directory only, please specify" \ 52"a complete repository." 53fi 54 55# make sure the links in the workdir have full paths to the original repo 56git_dir=$(cd "$git_dir" && pwd)||exit1 57 58# don't recreate a workdir over an existing directory, unless it's empty 59iftest -d"$new_workdir" 60then 61iftest$(ls -a1 "$new_workdir/." | wc -l)-ne2 62then 63 die "destination directory '$new_workdir' is not empty." 64fi 65 cleandir="$new_workdir/.git" 66else 67 cleandir="$new_workdir" 68fi 69 70mkdir-p"$new_workdir/.git"|| failed 71cleandir=$(cd "$cleandir" && pwd)|| failed 72 73cleanup () { 74rm-rf"$cleandir" 75} 76siglist="0 1 2 15" 77trap cleanup $siglist 78 79# create the links to the original repo. explicitly exclude index, HEAD and 80# logs/HEAD from the list since they are purely related to the current working 81# directory, and should not be shared. 82for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn 83do 84# create a containing directory if needed 85case$xin 86*/*) 87mkdir-p"$new_workdir/.git/${x%/*}" 88;; 89esac 90 91ln-s"$git_dir/$x""$new_workdir/.git/$x"|| failed 92done 93 94# commands below this are run in the context of the new workdir 95cd"$new_workdir"|| failed 96 97# copy the HEAD from the original repository as a default branch 98cp"$git_dir/HEAD" .git/HEAD || failed 99 100# the workdir is set up. if the checkout fails, the user can fix it. 101trap-$siglist 102 103# checkout the branch (either the same as HEAD from the original repository, 104# or the one that was asked for) 105git checkout -f$branch