Code

rebase -i: handle --continue more like non-interactive rebase
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Sun, 8 Jul 2007 02:01:29 +0000 (03:01 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jul 2007 01:24:19 +0000 (18:24 -0700)
Non-interactive rebase requires the working tree to be clean, but
applies what is in the index without requiring the user to do it
herself.  Imitate that, but (since we are interactive, after all)
fire up an editor with the commit message.

It also fixes a subtle bug: a forgotten "continue" was removed, which
led to an infinite loop when continuing without remaining patches.

Both issues noticed by Frank Lichtenheld.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-rebase--interactive.sh
t/t3404-rebase-interactive.sh

index 0c2a9697c4967efb98aabd5ea0c9a1e797234354..705178f7e9e95d3d0e9976902ff32e30e2a4b002 100755 (executable)
@@ -59,6 +59,10 @@ make_patch () {
 }
 
 die_with_patch () {
+       test -f "$DOTEST"/message ||
+               git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message
+       test -f "$DOTEST"/author-script ||
+               get_author_ident_from_commit $sha1 > "$DOTEST"/author-script
        make_patch "$1"
        die "$2"
 }
@@ -140,10 +144,7 @@ pick_one_preserving_merges () {
                        if ! git merge $STRATEGY -m "$msg" $new_parents
                        then
                                echo "$msg" > "$GIT_DIR"/MERGE_MSG
-                               warn Error redoing merge $sha1
-                               warn
-                               warn After fixup, please use
-                               die "$author_script git commit"
+                               die Error redoing merge $sha1
                        fi
                        ;;
                *)
@@ -154,11 +155,12 @@ pick_one_preserving_merges () {
 }
 
 do_next () {
+       test -f "$DOTEST"/message && rm "$DOTEST"/message
+       test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
        read command sha1 rest < "$TODO"
        case "$command" in
        \#|'')
                mark_action_done
-               continue
                ;;
        pick)
                comment_for_reflog pick
@@ -201,6 +203,7 @@ do_next () {
                git cat-file commit $sha1 | sed -e '1,/^$/d' >> "$MSG"
                git reset --soft HEAD^
                author_script=$(get_author_ident_from_commit $sha1)
+               echo "$author_script" > "$DOTEST"/author-script
                case $failed in
                f)
                        # This is like --amend, but with a different message
@@ -212,10 +215,6 @@ do_next () {
                        cp "$MSG" "$GIT_DIR"/MERGE_MSG
                        warn
                        warn "Could not apply $sha1... $rest"
-                       warn "After you fixed that, commit the result with"
-                       warn
-                       warn "  $(echo $author_script | tr '\012' ' ') \\"
-                       warn "    git commit -F \"$GIT_DIR\"/MERGE_MSG -e"
                        die_with_patch $sha1 ""
                esac
                ;;
@@ -265,6 +264,15 @@ do
 
                test -d "$DOTEST" || die "No interactive rebase running"
 
+               # commit if necessary
+               git rev-parse --verify HEAD > /dev/null &&
+               git update-index --refresh &&
+               git diff-files --quiet &&
+               ! git diff-index --cached --quiet HEAD &&
+               . "$DOTEST"/author-script &&
+               export GIT_AUTHOR_NAME GIT_AUTHOR_NAME GIT_AUTHOR_DATE &&
+               git commit -F "$DOTEST"/message -e
+
                require_clean_work_tree
                do_rest
                ;;
index 883cf29595366a6db17b7741ac11e13deb727070..c25133699a97e3e0e453dd62101e6f35558f8ceb 100755 (executable)
@@ -63,7 +63,10 @@ test_expect_success 'setup' '
 
 cat > fake-editor.sh << EOF
 #!/bin/sh
-test "\$1" = .git/COMMIT_EDITMSG && exit
+test "\$1" = .git/COMMIT_EDITMSG && {
+       test -z "\$FAKE_COMMIT_MESSAGE" || echo "\$FAKE_COMMIT_MESSAGE" > "\$1"
+       exit
+}
 test -z "\$FAKE_LINES" && exit
 grep -v "^#" < "\$1" > "\$1".tmp
 rm "\$1"
@@ -181,6 +184,7 @@ test_expect_success 'preserve merges with -p' '
        echo C > file1 &&
        test_tick &&
        git commit -m K file1 &&
+       test_tick &&
        git rebase -i -p --onto branch1 master &&
        test $(git rev-parse HEAD^^2) = $(git rev-parse to-be-preserved) &&
        test $(git rev-parse HEAD~3) = $(git rev-parse branch1) &&
@@ -188,4 +192,14 @@ test_expect_success 'preserve merges with -p' '
        test $(git show HEAD~2:file1) = B
 '
 
+test_expect_success '--continue tries to commit' '
+       test_tick &&
+       ! git rebase -i --onto new-branch1 HEAD^ &&
+       echo resolved > file1 &&
+       git add file1 &&
+       FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+       test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&
+       git show HEAD | grep chouette
+'
+
 test_done