git: 9front

Download patch

ref: cbc397384e190d18c4419de7ca59f8b10a6a84dc
parent: 89a03efcbd195f3e7675bd048041d3657185b03e
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Aug 24 15:04:30 EDT 2025

git/rebase: stop doing it.

git/rebase was a relatively clunky and error prone
script that would juggle around branches, make changes
to repository state, and ended up rather confusing.

it feels a lot better to use if we follow the example
of kill(1), where we print the commands that the user
may run, give them the opportunity to edit them, but
not take any action directly.

so let's do that.

--- a/sys/src/cmd/git/rebase
+++ b/sys/src/cmd/git/rebase
@@ -1,90 +1,39 @@
-#!/bin/rc
+#!/bin/rc -e
 
 . /sys/lib/git/common.rc
 gitup
 
-flagfmt='a:abort, r:resume, i:interactive'; args='onto'
+flagfmt='s:src src, n:nocommit'; args='onto'
 eval `''{aux/getflags $*} || exec aux/usage
+if(~ $#* 0) exec aux/usage
 
-tmp=_rebase.working
-if(~ $#abort 1){
-	if(! test -f .git/rebase.todo)
-		die no rebase to abort
-	src=`{cat .git/rebase.src}
-	rm -f .git/rebase.^(src todo)
-	git/branch $src
-	git/branch -r $tmp
-	exit
-}
-if(test -f .git/rebase.todo){
-	if(~ $#resume 0)
-		die rebase in progress
-	if(! ~ $#* 0)
-		exec aux/usage
-	src=`{cat .git/rebase.src}
-}
-if not{
-	if(! ~ $#* 1)
-		exec aux/usage
+if(~ $#src 0)
 	src=`{git/branch}
-	dst=`{git/query $1}
-	echo $src > .git/rebase.src
-	git/log -se $dst'..'$src | sed 's/^/pick /' >.git/rebase.todo
-	if(! ~ $#interactive 0){
-		giteditor=`{git/conf core.editor}
-		if(~ $#editor 0)
-			editor=$giteditor
-		if(~ $#editor 0)
-			editor=hold
-		$editor .git/rebase.todo
-	}
-	git/branch -nb $dst $tmp
+nflag=''
+if(~ $nocomit 1)
+	nflag='-n'
+	
+dst=`{git/query $1}
+com=`{git/query $dst  $src @}
+if(~ $dst $com)
+	die 'nothing to rebase, doofus'
+git/log -se $dst'..'$src  | awk '
+BEGIN{
+	src=ENVIRON["src"];
+	dst=ENVIRON["dst"];
 }
-todo=`$nl{cat .git/rebase.todo}
-
-fn sigexit {
-	s=$status
-	if(!)
-		echo 'fix and git/rebase -r'
-	>.git/rebase.todo for(i in $todo)
-		echo $i
-	status=$s
+{
+	if(!done)
+		print "git/branch -nb "dst" rebase.wip";
+	c=$1; $1="";
+	print "git/export "c" | git/import '$nflag'#"$0;
+	done=1
 }
-
-flag e +
-
-while(! ~ $#todo 0){
-	item=`{echo $todo(1)}
-	todo=$todo(2-)
-	echo $item
-	c=$item(2)
-	switch($item(1)){
-	case p pick
-		git/export $c | git/import
-	case r reword
-		git/export $c | git/import
-		git/commit -re
-	case e edit
-		git/export $c | git/import
-		echo 'stopped for edit, resume with git/rebase -r'
-		exit
-	case s squash
-		git/export $c | git/import -n
-		msg=`''{cat $gitfs/HEAD/msg; echo; cat $gitfs/object/$c/msg}
-		git/commit -rem $msg .
-	case f fixup
-		git/export $c | git/import -n
-		git/commit -r .
-	case b break
-		echo 'stopped, resume with git/rebase -r'
-		exit
-	case '#'* ''
-	case *
-		die 'unknown command '''^$item(1)^''''
+END{
+	if(!done)
+		print "git/branch -nb "dst" ";
+	else{
+		print "git/branch -nb rebase.wip "src
+		print "git/branch -r rebase.wip";
 	}
-}
-
-fn sigexit
-git/branch -nb $tmp $src
-git/branch -r $tmp
-rm .git/rebase.todo .git/rebase.src
+}' 
--- a/sys/src/cmd/git/test/rebase.rc
+++ b/sys/src/cmd/git/test/rebase.rc
@@ -21,6 +21,7 @@
 	q git/add b
 	q git/commit -m b b
 
+	q git/fs
 	q git/branch front-test
-	q git/rebase front
+	q git/rebase front | rc
 }
--