shithub: git9

Download patch

ref: c9e501828bd3fdc1309859730530e1968fc28190
parent: 118584c48da15d064d7df58dc7c4e481a18ebb77
author: Michael Forney <mforney@mforney.org>
date: Thu Feb 4 00:34:22 EST 2021

git/rebase: initial implementation of interactive mode (-i)

--- a/git.1.man
+++ b/git.1.man
@@ -120,7 +120,7 @@
 .PP
 .B git/rebase
 [
-.B -ar
+.B -ari
 ]
 [
 .B onto
@@ -430,6 +430,33 @@
 .I -a
 option will clean up the in progress rebase
 and reset the state of the branch.
+The
+.I -i
+option will open an editor to modify the todo-list before the rebase
+begins.
+
+.PP
+The following rebase commands are supported:
+.TP 10
+.B pick
+Apply the commit.
+.TP
+.B reword
+Apply the commit, then edit its commit message.
+.TP
+.B edit
+Apply the commit, then exit to allow further changes.
+.TP
+.B squash
+Fold the commit into the previous commit, then edit the combined
+commit message.
+.TP
+.B fixup
+Fold the commit into the previous commit, discarding its commit
+message.
+.TP
+.B break
+Exit to allow for manual edits or inspection before continuing.
 
 .PP
 .B Git/conf
--- a/rebase
+++ b/rebase
@@ -3,7 +3,7 @@
 . /sys/lib/git/common.rc
 gitup
 
-flagfmt='a:abort, r:resume'; args='onto'
+flagfmt='a:abort, r:resume, i:interactive'; args='onto'
 eval `''{aux/getflags $*} || exec aux/usage
 
 tmp=_rebase.working
@@ -24,7 +24,6 @@
 	if(! ~ $#* 0)
 		exec aux/usage
 	src=`{cat .git/rebase.src}
-	commits=`{cat .git/rebase.todo}
 }
 if not{
 	if(! ~ $#* 1)
@@ -31,20 +30,62 @@
 		exec aux/usage
 	src=`{git/branch}
 	dst=`{git/query $1}
-	commits=`{git/query $dst $src @ .. $src}
-	## TODO: edit $commits here for -i
+	echo $src > .git/rebase.src
+	git/log -se $dst' '$src' @ .. '$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
 }
+todo=`$nl{cat .git/rebase.todo}
 
-while(! ~ $#commits 0){
-	c=$commits(1)
-	commits=$commits(2-)
-	if(! git/export $c | git/import){
-		echo $src > .git/rebase.src
-		echo $commits > .git/rebase.todo
-		die $c: fix and git/rebase -r
+fn sigexit {
+	s=$status
+	if(!){
+		echo $todo > .git/rebase.todo
+		echo 'fix and git/rebase -r'
 	}
+	status=$s
 }
 
+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 /mnt/git/HEAD/msg; echo; cat /mnt/git/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)^''''
+	}
+}
+
 git/branch -nb $tmp $src
 git/branch -d $tmp
+rm .git/rebase.todo .git/rebase.src