136 lines · 3.1 KB · Text
RawDownload
#!/bin/rc -erfork en. /sys/lib/git/common.rc gitup flagfmt='a:listall, b:baseref ref, r:remove, n:newbr, s:stay, m:merge, M:nomod'args='[branch]'eval `''{aux/getflags $*} || exec aux/usage modified=()deleted=()failed=()if(~ $#* 0){	if(~ $#listall 0)		awk '$1=="branch"{print $2}' < $gitfs/ctl	if not		cd .git/refs/ && walk -f heads remotes | sort	exit}if(! ~ $#* 1)	exec aux/usage branch=$1if(~ $branch refs/heads/*)	new=$nameif not if(~ $branch heads/*)	new=refs/$branchif not	new=refs/heads/$branch # where are we now?orig=`{git/query HEAD}origbranch=refs/`{awk '$1=="branch"{print $2}' < $gitfs/ctl} # if we're switching branches to a branch that doesn't exist,# but we have a remote branch that exists upstream, create a# new head to mirror it.if(~ $#newbr 0){	if(! ~ $#baseref 0)		die update would clobber $branch with $baseref	if(! test -e .git/$new){		baseref=`$nl{echo -n $new | sed s@refs/heads/@refs/remotes/origin/@}		if(! base=`{git/query $baseref})			exit 'bad ref'	}} # figure out where we want the new branch to point toif (~ $#baseref 1)	base=`{git/query $baseref} || exit 'bad ref'if not if(~ $#newbr 0)	base=`{git/query $new} || exit 'bad ref'if not	base=`{git/query HEAD} || exit 'bad ref' modified=`$nl{git/query -c HEAD $base | grep '^[^-]' | subst '^..'}deleted=`$nl{git/query -c HEAD $base | grep '^-' | subst '^..'} # if we remove the current branch without switching, bad things happenif(~ $remove 1 && ~ $origbranch $new)	die 'cannot remove current branch'# if we're not merging, don't clobber existing changes.if(~ $#merge 0 && ~ $#remove 0){	if(! ~ $#modified 0 || ! ~ $#deleted 0){		git/walk -fRMA $modified $deleted || 			die 'uncommitted changes would be clobbered'	}}if(~ $remove 1){	rm -f .git/$new	echo 'removed branch' $new	exit}commit=`{git/query $base} || die 'branch does not exist:' $basebasedir=`{git/query -p $base}dirtypaths=()if(! ~ $#modified 0 || ! ~ $#deleted 0)	dirtypaths=`$nl{git/walk -cfRMA $modified $deleted} >>[3].git/INDEX9{	for(d in $deleted){		if(! test -d $d){			rm -f $d			echo R NOQID 0 $d >>[1=3]		}	}	for(m in $modified $deleted) if(! ~ $m $dirtypaths){		d=`$nl{basename -d $m}		mkdir -p $d		# Modifications can turn a file into		# a directory, or vice versa, so we		# need to delete and copy the files		# over.		a=dir		b=dir		if(test -f $m)			a=file		if(test -f $basedir/tree/$m)			b=file		if(! ~ $a $b){			rm -rf $m			echo R NOQID 0 $m >>[1=3]		}		if(~ $b file){			echo T NOQID 0 $m >>[1=3]			cp -x -- $basedir/tree/$m $m || {echo cp failed: $m; failed=1}			touch -c $m		}	}}modified=()deleted=() for(ours in $dirtypaths){	common=$gitfs/object/$orig/tree/$ours	theirs=$gitfs/object/$base/tree/$ours	merge1 $ours $ours $common $theirs	st=$status	if(! ~ $st '')		>[1=2] echo merge failed $ours: $st}dirtypaths=() if(~ $new */*)	mkdir -p .git/`{basename -d $new}echo $commit > .git/$newif(! ~ $#stay 0)	exitif(~ $failed 1){	echo 'pull failed: fix errors and try again' >[1=2]	exit nopull}echo ref: $new > .git/HEADecho $new: `{git/query $new}exit ''