shithub: git9

ref: 752da3f533f70b9f3fa9c48c635c860468ee1054
dir: /clone/

View raw version
#!/bin/rc
rfork en
. /sys/lib/git/common.rc

flagfmt='d:debug'; args='remote [local]'
eval `''{aux/getflags $*} || exec aux/usage
if(~ $debug 1)
	debug=(-d)

remote=`{echo $1 | subst -g '/*$'}
local=$2

if(~ $#remote 0)
	exec aux/usage
if(~ $#local 0)
	local=`{basename $remote .git}

if(test -e $local)
	die 'repository already exists:' $local

fn clone{
	flag +e
	mkdir -p $local/.git
	mkdir -p $local/.git/objects/pack/
	mkdir -p $local/.git/refs/heads/
	
	cd $local
	
	dircp /sys/lib/git/template .git
	>>.git/config {
		echo '[remote "origin"]'
		echo '	url='$remote
		echo '	fetch=+refs/heads/*:refs/remotes/origin/*'
	}
	{git/fetch $debug $remote >[2=3] | awk '
		BEGIN{
			headref=""
			headhash=""
		}
		/^symref /{
			if($2 == "HEAD"){
				gsub("^refs/heads", "refs/remotes/origin", $3)
				gsub("^refs/tags", "refs/remotes/origin/tags", $3)
				headref=$3
			}
		}
		/^remote /{
			if($2=="HEAD"){
				headhash=$3
			}else if(match($2, "^refs/(heads|tags)/")){
				gsub("^refs/heads", "refs/remotes/origin", $2)
				if($2 == headref || (headref == "" && $3 == headhash))
					headref=$2
				outfile = ".git/" $2
				outdir = outfile
				gsub("/?[^/]*/?$", "", outdir)
				system("mkdir -p "outdir)
				print $3 > outfile
				close(outfile)
			}
		}
		END{
			if(headref != ""){
				remote = headref;
				refdir = headref;
				gsub("/?[^/]*/?$", "", refdir)
				gsub("^refs/remotes/origin", "refs/heads", headref)
				system("mkdir -p .git/"refdir);
				system("cp .git/" remote " .git/" headref)
				print "ref: " headref > ".git/HEAD"
			}else if(headhash != ""){
				print "warning: detached head "headhash > "/fd/2"
				print headhash > ".git/HEAD"
			}
		}
	'} |[3] tr '\x0d' '\x0a' || die 'could not clone repository'

	tree=/mnt/git/HEAD/tree
	lbranch=`{git/branch}
	rbranch=`{echo $lbranch | subst '^heads' 'remotes/origin'}
	echo checking out repository...
	if(test -f .git/refs/$rbranch){
		cp .git/refs/$rbranch .git/refs/$lbranch
		git/fs
		@ {builtin cd $tree && tar cif /fd/1 .} | @ {tar xf /fd/0} \
			|| die 'checkout failed:' $status
		for(f in `$nl{walk -f $tree | subst '^'$tree'/*'}){
			if(! ~ $#f 0){
				idx=.git/index9/tracked/$f
				mkdir -p `$nl{basename -d $idx}
				walk -eq $f > $idx
			}
		}
	}
	if not{
		echo no master branch >[1=2]
		echo check out your code with git/branch >[1=2]
	}
}

fn sigint {
	echo cancelled clone $remote: cleaning $local >[1=2]
	rm -rf $local
	exit interrupted
}

@{clone}
st=$status
if(! ~ $st ''){
	echo failed to clone $remote: cleaning $local >[1=2]
	rm -rf $local
	exit $st
}
exit ''