ref: deb7402afe2b7b4a047760442e1cfe6d1891bf47
parent: cfcc9e9a57d5daa0add014c83b23ae0eb0f77e84
author: Ori Bernstein <[email protected]>
date: Fri Dec 4 21:48:16 EST 2020
git/rebase: first cut of rebase implementation Implement the basic version of git/rebase, handling rewriting commits on one branch as though they were based off a different branch. Rebasing starts by finding the least common ancestor of the two branches, and then replaying every commit from the source branch on to the destination branch, then renaming the source branch. In the case of a conflict, the commits are dumped to a temp file, and the rebase is paused until the user either aborts the rebase or resolves the issue and resumes the rebase.
--- a/git.1.man
+++ b/git.1.man
@@ -116,6 +116,14 @@
.B git/merge
.I theirs
.PP
+.B git/rebase
+[
+.B -ar
+]
+[
+.B onto
+]
+.PP
.B git/pull
[
.B -f
@@ -402,6 +410,19 @@
takes two branches and merges them filewise using
.I ape/diff3.
The next commit made will be a merge commmit.
+
+.PP
+.B Git/rebase
+takes one branch and moves it onto another.
+On error, the remaining commits to rebase are
+saved, and can be resumed once the conflict is
+resolved using the
+.I -r
+option.
+If the rebase is to be aborted, the
+.I -a
+option will clean up the in progress rebase
+and reset the state of the branch.
.PP
.B Git/conf
--- a/import
+++ b/import
@@ -1,4 +1,4 @@
-#!/bin/rc
+#!/bin/rc -x
rfork ne
. /sys/lib/git/common.rc
@@ -69,7 +69,7 @@
rc -c '
echo applying $msg | sed 1q
date=`{seconds $date}
- if(! files=`$nl{ape/patch -Ep1 < $diffpath | grep '^patching file' | sed ''s/^patching file `(.*)''''/\1/''})
+ if(! files=`$nl{ape/patch -Ep1 < $diffpath | grep ''^patching file'' | sed ''s/^patching file `(.*)''''/\1/''})
die ''patch failed''
for(f in $files){
if(test -e $f)
--- a/mkfile
+++ b/mkfile
@@ -26,6 +26,7 @@
merge\
pull\
push\
+ rebase\
revert\
rm
--- /dev/null
+++ b/rebase
@@ -1,0 +1,52 @@
+#!/bin/rc
+
+. /sys/lib/git/common.rc
+gitup
+
+flagfmt='a:abort, r:resume'; args='onto'
+eval `''{aux/getflags $*} || exec aux/usage
+
+tmp=_rebase.working
+if(! git/walk -q)
+ die dirty working tree
+if(~ $#abort 1){
+ if(! test -f .git/rebase.todo)
+ die no rebase to abort
+ src=`{cat .git/rebase.src}
+ rm -f .git/rebase.^(src dst todo)
+ git/branch $src
+ git/branch -d $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}
+ dst=`{cat .git/rebase.dst}
+ commits=`{cat .git/rebase.todo}
+}
+if not{
+ if(! ~ $#* 1)
+ exec aux/usage
+ src=`{git/branch}
+ dst=`{git/query $1}
+ commits=`{git/query $onto $src @ .. $src}
+ ## TODO: edit $commits here for -i
+}
+
+git/branch -nb $dst $tmp
+while(! ~ $#commmits 0){
+ c=$commits(1)
+ commits=$commits(2-)
+ if(! git/export $c | git/import){
+ echo $src > .git/rebase.src
+ echo $dst > .git/rebase.dst
+ echo $commits > .git/rebase.todo
+ die $c: fix and git/rebase -r
+ }
+}
+
+git/branch -nb $tmp $src
+git/branch -d $tmp