198 lines · 4.0 KB · Text
RawDownload
#!/bin/rc -erfork ne. /sys/lib/git/common.rc fn findbranch{	branch=`{git/branch}	if(test -e $gitfs/branch/$branch/tree){		refpath=.git/refs/$branch		initial=false	}	if not if(test -e $gitfs/object/$branch/tree){		refpath=.git/HEAD		initial=false	}	if not if(! test -e $gitfs/HEAD/tree){		refpath=.git/refs/$branch		initial=true	}	if not		die 'invalid branch:' $branch} # Remove commentary lines.# Remove leading and trailing empty lines.# Combine consecutive empty lines between paragraphs.# Remove trailing spaces from lines.# Ensure there's trailing newline.fn cleanmsg{	awk '	/^[ 	]*#/ {next}	/^[ 	]*$/ {empty = 1; next} 	wet && empty {printf "\n"}	{wet = 1; empty = 0}	{sub(/[ 	]+$/, ""); print $0}	'} fn editmsg{	if(! test -s $msgfile.tmp){		>$msgfile.tmp {			echo '# Author:' $name '<'$email'>'			echo '#'			for(p in $parents)				echo '# parent:' $p			git/walk -fAMR $files | subst '^' '# '			echo '#'			echo '# Commit message:'		}		edit=1	}	if(! ~ $#edit 0){		giteditor=`{git/conf core.editor}		if(~ $#editor 0)			editor=$giteditor		if(~ $#editor 0)			editor=hold		$editor $msgfile.tmp	}	cleanmsg < $msgfile.tmp > $msgfile	if(! test -s $msgfile)		die 'empty commit message'} fn parents{	if(! ~ $#revise 0)		parents=`{cat $gitfs/HEAD/parent}	if not if(test -f .git/merge-parents)		parents=`{cat .git/merge-parents | sort | uniq}	if not if(~ $initial true)		parents=()	if not		parents=`{git/query $branch}} fn commit{	msg=`''{cat $msgfile}	if(! ~ $#parents 0)		pflags='-p'^$parents	hash=`{git/save -n $"name -e $"email -m $"msg $pflags $files || die $status}} fn update{	mkdir -p `{basename -d $refpath}	# Paranoia: let's not mangle the repo.	if(~ $#hash 0)		die 'botched commit'	rm -f .git/merge-parents	echo $branch: $hash	echo $hash > $refpath	for(f in $files){		if(! test -e $f && ! test -e .git/object/$hash/tree/$f)			echo R NOQID 0 $f >> .git/INDEX9		if not			echo T NOQID 0 $f >> .git/INDEX9	}} fn filterdiff{	awk '		function dump(){			if(n == 0)				return 			print "--- a/"f >>"/dev/cons"			print "+++ b/"f >>"/dev/cons"			for(i = 0; i < n; i++)				print lines[i] >>"/dev/cons"			printf("Commit this hunk?[n]  ") >>"/dev/cons"			getline ans < "/dev/cons"			if(ans ~ /[yY]/)				for(i = 0; i < n; i++)					print lines[i]			n = 0		}		/^---/{ next }		/^\+\+\+/{			f = substr($0, 5)			print "--- "f			print "+++ "f			n = 0			next		}		/^@@/{ dump() }		{ lines[n++] = $0 }		END{ dump() }	'} fn pickhunks{	p=$wdir/patch	if(test -f .git/fs/HEAD/tree/$i)		#<[12]/fd/0 >[13]/fd/1 { diff -u .git/fs/HEAD/tree/$1 $1 | filterdiff >>$p }		{ diff -u .git/fs/HEAD/tree/$1 $1 | filterdiff >>$p } || status=''	if not		diff -u /dev/null $1 >>$p || status=''} fn apply{	t=$wdir/tree/	p=$wdir/patch	ln=`{wc -l $p}	if(test $ln(1) -lt 3)		die 'no hunks seleted'	# replace the global var so if no hunks were selected, we don't commit it	files=`{patch -n $p}	mkdir $t	@{cd .git/fs/HEAD/tree; tar c $files >[2]/dev/null} | @{cd $t; tar xT}	for(i in $files){		d=`{basename -d $i}		if(! test -d $d){			mkdir -p $t/$d			bind -bc $t/$d $d		}	}	bind -bc $t .	patch <$p >/dev/null || die 'failed partial patch: '^$status} gitup flagfmt='m:msg message, r:revise, e:edit, p:partial'; args='[file ...]'eval `''{aux/getflags $*} || exec aux/usage wdir=/mnt/gitramfs -m $wdirmsgfile=$wdir/git-msg.$pidif(~ $#msg 1)	echo $msg >$msgfile.tmpif not if(~ $#revise 1){	msg=1	echo revising commit `{cat $gitfs/HEAD/hash}	cat $gitfs/HEAD/msg >$msgfile.tmp} files=()if(test -f .git/merge-parents)	files=`$nl{git/query -c `{cat .git/merge-parents} | sed 's/^..//'}if(! ~ $#* 0)	files=($files `$nl{git/walk -fRMA -c `$nl{cleanname -d $gitrel $*}})if(~ $status '' || ~ $#files 0 && ! test -f .git/merge-parents && ~ $#revise 0)	die 'nothing to commit'if(~ $#partial 1){	for(i in $files)		pickhunks $i	apply} @{	flag e +	whoami	findbranch	parents	editmsg	commit	update} || die 'could not commit:' $statusexit ''