This will store the difference between HEAD and the index into a commit, and the difference between the index and the working tree into a commit. When the rebase is done, it restores the index and the working tree by undoing these commits with git-reset. Signed-off-by: Simon Sasburg <Simon.Sasburg@xxxxxxxxx> --- git-rebase.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 54 insertions(+), 9 deletions(-) diff --git a/git-rebase.sh b/git-rebase.sh index 224cca9..c923c3b 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -42,6 +42,7 @@ To restore the original branch and stop rebasing run \"git rebase --abort\". unset newbase strategy=recursive do_merge= +fix_dirty= dotest=$GIT_DIR/.dotest-merge prec=4 verbose= @@ -117,9 +118,39 @@ call_merge () { finish_rb_merge () { rm -r "$dotest" + restore_dirty_state echo "All done." } +store_dirty_state () { + echo "Storing dirty index/working tree" + diff=$(git diff --cached) + case "$diff" in + ?*) git commit -m "REBASE--dirty: store HEAD..index diff" + ;; + esac + diff=$(git diff) + case "$diff" in + ?*) git commit -a -m "REBASE--dirty: store index..workingtree diff" + ;; + esac +} + +restore_dirty_state () { + lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::") + if test "$lastmsg" = "REBASE--dirty: store index..workingtree diff" + then + echo "Restoring dirty index state" + git reset --mixed HEAD^ + fi + lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::") + if test "$lastmsg" = "REBASE--dirty: store HEAD..index diff" + then + echo "Restoring dirty working dir state" + git reset --soft HEAD^ + fi +} + is_interactive () { test -f "$dotest"/interactive || while :; do case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac @@ -156,6 +187,10 @@ do git am --resolved --3way --resolvemsg="$RESOLVEMSG" exit ;; + --dirty) + do_merge=t + fix_dirty=t + ;; --skip) if test -d "$dotest" then @@ -188,6 +223,7 @@ do die "No rebase in progress?" fi git reset --hard ORIG_HEAD + restore_dirty_state exit ;; --onto) @@ -253,15 +289,19 @@ else fi fi -# The tree must be really really clean. -git update-index --refresh || exit -diff=$(git diff-index --cached --name-status -r HEAD) -case "$diff" in -?*) echo "cannot rebase: your index is not up-to-date" - echo "$diff" - exit 1 - ;; -esac +# The tree must be really really clean, unless --dirty is given. +if test "$fix_dirty" = "" +then + git update-index --refresh || exit + diff=$(git diff-index --cached --name-status -r HEAD) + case "$diff" in + ?*) echo "cannot rebase: your index is not up-to-date" + echo "$diff" + exit 1 + ;; + esac + +fi # The upstream head must be given. Make sure it is valid. upstream_name="$1" @@ -318,6 +358,11 @@ then GIT_PAGER='' git diff --stat --summary "$mb" "$onto" fi +if test "$fix_dirty" = "t" +then + store_dirty_state +fi + # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD. echo "First, rewinding head to replay your work on top of it..." git-reset --hard "$onto" -- 1.5.3.4.502.g37c97 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html