git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 16/18] rebase -i: For fixup commands without squashes, do not start editor

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Jan 14, 2010, 05:54 UTC
Message-ID
<6f72a672c95fd955508d9efa483cd4fa742a137e.1263447038.git.mhagger@alum.mit.edu>
In-Reply-To
<cover.1263447037.git.mhagger@alum.mit.edu>

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 <mhagger@alum.mit.edu>
---
 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 5a48fbf..c9390cd 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -66,6 +66,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
@@ -360,7 +367,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 \
@@ -373,16 +380,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
@@ -457,7 +466,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"
@@ -466,34 +475,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 0511709..175a86c 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
 '
-- 
1.6.6
Previous: Johannes SixtNext: Michael Haggerty
Message 30 of 34 in “rebase -i: For pure fixups, do not start log message editor”
  1. 00/18 rebase -i: For pure fixups, do not start log message editorMichael Haggerty, Jan 14, 2010
  2. 01/18 rebase -i: Make the condition for an "if" more transparentMichael Haggerty, Jan 14, 2010
  3. Eric BlakeJan 14, 2010
  4. Junio C HamanoJan 14, 2010
  5. Paolo BonziniJan 15, 2010
  6. Johannes SchindelinJan 25, 2010
  7. Michael HaggertyJan 26, 2010
  8. Johannes SchindelinJan 26, 2010
  9. 02/18 rebase -i: Remove dead codeMichael Haggerty, Jan 14, 2010
  10. 03/18 rebase -i: Inline expressionMichael Haggerty, Jan 14, 2010
  11. 04/18 rebase -i: Use "test -n" instead of "test ! -z"Michael Haggerty, Jan 14, 2010
  12. 05/18 rebase -i: Use symbolic constant $MSG consistentlyMichael Haggerty, Jan 14, 2010
  13. 06/18 rebase -i: Document how temporary files are usedMichael Haggerty, Jan 14, 2010
  14. Greg PriceJan 25, 2010
  15. 07/18 rebase -i: Introduce a constant AUTHOR_SCRIPTMichael Haggerty, Jan 14, 2010
  16. 08/18 rebase -i: Introduce a constant AMENDMichael Haggerty, Jan 14, 2010
  17. 09/18 t3404: Test the commit count in commit messages generated by "rebase -i"Michael Haggerty, Jan 14, 2010
  18. Johannes SixtJan 14, 2010
  19. Michael HaggertyJan 14, 2010
  20. Johannes SixtJan 14, 2010
  21. 10/18 rebase -i: Improve consistency of commit count in generated commit messagesMichael Haggerty, Jan 14, 2010
  22. Johannes SixtJan 14, 2010
  23. Michael HaggertyJan 14, 2010
  24. 11/18 rebase -i: Simplify commit counting for generated commit messagesMichael Haggerty, Jan 14, 2010
  25. 12/18 rebase -i: Extract a function "commit_message"Michael Haggerty, Jan 14, 2010
  26. 13/18 rebase -i: Handle the author script all in one place in do_nextMichael Haggerty, Jan 14, 2010
  27. 14/18 rebase -i: Extract function do_with_authorMichael Haggerty, Jan 14, 2010
  28. 15/18 rebase -i: Change function make_squash_message into update_squash_messageMichael Haggerty, Jan 14, 2010
  29. Johannes SixtJan 14, 2010
  30. 16/18 rebase -i: For fixup commands without squashes, do not start editorMichael Haggerty, Jan 14, 2010
  31. 17/18 t3404: Set up more of the test repo in the "setup" stepMichael Haggerty, Jan 14, 2010
  32. 18/18 rebase -i: Retain user-edited commit messages after squash/fixup conflictsMichael Haggerty, Jan 14, 2010
  33. Junio C HamanoJan 14, 2010
  34. Johannes SchindelinJan 25, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.