shithub: git9

ref: 5577b5b51e56f5d043a9830903b2fb668f8451d1
dir: /branch/

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

usage='
	git/branch [-cdsu] [-b base] [branch]
		-b base   base new branch on "base" (default: current branch)
		-n        create new branch, or overwrite existing branch
		-d        delete branch
		-s        create branch but stay on current one
'

gitup

stay=()
newbr=()
delete=()
baseref=()
modified=()
deleted=()
listall=()

while(~ $1 -* && ! ~ $1 --){
	switch($1){
	case -n; newbr=true
	case -s; stay=true
	case -b; baseref=$2; shift
	case -d; delete=true
	case -a; listall=true
	case *
		usage
	}
	shift
}
if(~ $1 --)
	shift

if(~ $#* 0){
	if(~ $#listall 0)
		awk '$1=="branch"{print $2}' < /mnt/git/ctl
	if not
		cd .git/refs/ && walk -f heads remotes
	exit
}
if(! ~ $#* 1)
	usage

if(~ $1 refs/heads/*)
	new=$1
if not if(~ $1 heads/*)
	new=refs/$1
if not
	new=refs/heads/$1
if (~ $#baseref 1){
	base=`{git/query $baseref}
	if(! ~ $status '')
		exit badbase
}
if not if(test -e .git/$new)
	base=`{git/query $new}
if not
	base=`{git/query HEAD}

modified=`$nl{git/query -c HEAD $base | grep '^[^-]' | subst '^..'}
deleted=`$nl{git/query -c HEAD $base | grep '^-' | subst '^..'}

if(! ~ $#modified 0 || ! ~ $#deleted 0){
	if(! git/walk -q $modified $deleted){
		git/walk -fRMA $modified $deleted
		die 'uncommited changes would be clobbered'
	}
}
if(! ~ $#delete 0){
	rm -f .git/$new
	exit
}
if(~ $#newbr 0){
	if(! test -e .git/$new)
		die could not find branch $1
	if(! ~ $#baseref 0)
		die update would clobber $1 with $baseref
}
commit=`{git/query $base || die 'branch does not exist:' $base}
echo updating $new to $commit
echo $commit > .git/$new


if(! ~ $#stay 0)
	exit

if(! ~ $#modified 0){
	basedir=`{git/query -p $base}
	for(m in $modified){
		d=`{basename -d $m}
		mkdir -p $d
		mkdir -p .git/index9/tracked/$d
		# Modifications can turn a file into
		# a directory, or vice versa, so we
		# need to delete and copy the files
		# over. If we're checking out a
		a=`{test -f $m && echo file || echo dir}
		b=`{test -f $basedir/tree/$m && echo file || echo dir}
		if(! ~ $a $b){
			rm -rf $m
			rm -rf .git/index9/tracked/$m
		}
		if(test -f $basedir/tree/$m){
			cp  $basedir/tree/$m $m
			walk -eq $m > .git/index9/tracked/$m
		}
	}
}
if(! ~ $#deleted 0){
	rm -f $deleted
	rm -f .git/index9/tracked/$deleted
}

echo ref: $new > .git/HEAD