From a25eb13909088f04f87acec26c522cc555f6b4a9 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 14 Jan 2010 06:54:55 +0100 Subject: [PATCH] rebase -i: For fixup commands without squashes, do not start editor If the "rebase -i" commands include a series of fixup commands without any squash commands, then commit the combined commit using the commit message of the corresponding "pick" without starting up the commit-message editor. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 81 +++++++++++++++++++++++------------ t/t3404-rebase-interactive.sh | 7 ++- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index d8c3c9aac..1569a7ad9 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -65,6 +65,13 @@ MSG="$DOTEST"/message # updated. It is deleted just before the combined commit is made. SQUASH_MSG="$DOTEST"/message-squash +# If the current series of squash/fixups has not yet included a squash +# command, then this file exists and holds the commit message of the +# original "pick" commit. (If the series ends without a "squash" +# command, then this can be used as the commit message of the combined +# commit without opening the editor.) +FIXUP_MSG="$DOTEST"/message-fixup + # $REWRITTEN is the name of a directory containing files for each # commit that is reachable by at least one merge base of $HEAD and # $UPSTREAM. They are not necessarily rewritten, but their children @@ -358,7 +365,7 @@ nth_string () { esac } -update_squash_message () { +update_squash_messages () { if test -f "$SQUASH_MSG"; then mv "$SQUASH_MSG" "$SQUASH_MSG".bak || exit COUNT=$(($(sed -n \ @@ -371,16 +378,18 @@ update_squash_message () { }' <"$SQUASH_MSG".bak } >$SQUASH_MSG else + commit_message HEAD > "$FIXUP_MSG" || die "Cannot write $FIXUP_MSG" COUNT=2 { echo "# This is a combination of 2 commits." echo "# The first commit's message is:" echo - commit_message HEAD + cat "$FIXUP_MSG" } >$SQUASH_MSG fi case $1 in squash) + rm -f "$FIXUP_MSG" echo echo "# This is the $(nth_string $COUNT) commit message:" echo @@ -455,7 +464,7 @@ do_next () { die "Cannot '$squash_style' without a previous commit" mark_action_done - update_squash_message $squash_style $sha1 + update_squash_messages $squash_style $sha1 failed=f author_script=$(get_author_ident_from_commit HEAD) echo "$author_script" > "$AUTHOR_SCRIPT" @@ -464,34 +473,52 @@ do_next () { pick_one -n $sha1 || failed=t case "$(peek_next_command)" in squash|s|fixup|f) - USE_OUTPUT=output - cp "$SQUASH_MSG" "$MSG" || exit - MSG_OPT=-F - EDIT_OR_FILE="$MSG" + # This is an intermediate commit; its message will only be + # used in case of trouble. So use the long version: + if test $failed = f + then + do_with_author output git commit --no-verify -F "$SQUASH_MSG" || + failed=t + fi + if test $failed = t + then + cp "$SQUASH_MSG" "$MSG" || exit + # After any kind of hiccup, prevent committing without + # opening the commit message editor: + rm -f "$FIXUP_MSG" + cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit + warn + warn "Could not apply $sha1... $rest" + die_with_patch $sha1 "" + fi ;; *) - USE_OUTPUT= - MSG_OPT= - EDIT_OR_FILE=-e - cp "$SQUASH_MSG" "$MSG" || exit - mv "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit - rm -f "$GIT_DIR"/MERGE_MSG || exit + # This is the final command of this squash/fixup group + if test $failed = f + then + if test -f "$FIXUP_MSG" + then + do_with_author git commit --no-verify -F "$FIXUP_MSG" || + failed=t + else + cp "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit + rm -f "$GIT_DIR"/MERGE_MSG + do_with_author git commit --no-verify -e || + failed=t + fi + fi + rm -f "$FIXUP_MSG" + if test $failed = t + then + mv "$SQUASH_MSG" "$MSG" || exit + cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit + warn + warn "Could not apply $sha1... $rest" + die_with_patch $sha1 "" + fi + rm -f "$SQUASH_MSG" ;; esac - if test $failed = f - then - # This is like --amend, but with a different message - do_with_author $USE_OUTPUT git commit --no-verify \ - $MSG_OPT "$EDIT_OR_FILE" || - failed=t - fi - if test $failed = t - then - cp "$MSG" "$GIT_DIR"/MERGE_MSG - warn - warn "Could not apply $sha1... $rest" - die_with_patch $sha1 "" - fi ;; *) warn "Unknown command: $command $sha1 $rest" diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 05117091e..175a86c2c 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -237,14 +237,13 @@ test_expect_success 'multi-squash only fires up editor once' ' test 1 = $(git show | grep ONCE | wc -l) ' -test_expect_success 'multi-fixup only fires up editor once' ' +test_expect_success 'multi-fixup does not fire up editor' ' git checkout -b multi-fixup E && base=$(git rev-parse HEAD~4) && - FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \ - EXPECT_HEADER_COUNT=4 \ + FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \ git rebase -i $base && test $base = $(git rev-parse HEAD^) && - test 1 = $(git show | grep ONCE | wc -l) && + test 0 = $(git show | grep NEVER | wc -l) && git checkout to-be-rebased && git branch -D multi-fixup ' -- 2.30.2