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

[RFC PATCH 2/7] rebase -i: Teach do_pick the option --edit

From
Fabian Ruch <bafain@gmail.com>
Date
Jun 19, 2014, 03:28 UTC
Message-ID
<53A258DE.10407@gmail.com>
In-Reply-To
<cover.1403146774.git.bafain@gmail.com>

The to-do list command `reword` replays a commit like `pick` but lets the user also edit the commit's log message. If one thinks of `pick` entries as scheduled `cherry-pick` command lines, then `reword` becomes an alias for the command line `cherry-pick --edit`. The porcelain `rebase--interactive` defines a function `do_pick` for processing the `pick` entries on to-do lists. Teach `do_pick` to handle the option `--edit` and reimplement `reword` in terms of `do_pick --edit`. Refer to `pick_one` for the way options are parsed.

`do_pick` ought to act as a wrapper around `cherry-pick`. Unfortunately, it cannot just forward `--edit` to the `cherry-pick` command line. The assembled command line is executed within a command substitution for controlling the verbosity of `rebase--interactive`. Passing `--edit` would either hang the terminal or clutter the substituted command output with control sequences. Execute the `reword` code from `do_next` instead if the option `--edit` is specified. Adjust the fragment in two regards. Firstly, discard the additional message which is printed if an error occurs because

    Aborting commit due to empty commit message. (Duplicate Signed-off-by lines.)
    Could not amend commit after successfully picking 1234567... Some change
is more readable than and contains (almost) the same information as
    Aborting commit due to empty commit message. (Duplicate Signed-off-by lines.)
    Could not amend commit after successfully picking 1234567... Some change
    This is most likely due to an empty commit message, or the pre-commit hook
    failed. If the pre-commit hook failed, you may need to resolve the issue before
    you are able to reword the commit.

(It is true that a hook might not output any diagnosis but the same problem arises when using git-commit directly. git-rebase at least prints a generic message saying that it failed to commit.) Secondly, sneak in additional git-commit arguments:

 - `--allow-empty` is missing: `rebase--interactive` suddenly fails if
   an empty commit is picked using `reword` instead of `pick`. The
   whether a commit is empty or not is not changed by an altered log
   message, so do as `pick` does. Add test.
 - `-n`: Hide the fact that we are committing several times by not
   executing the pre-commit hook. Caveat: The altered log message is not
   verified because `-n` also skips the commit-msg hook. Either the log
   message verification must be included in the post-rewrite hook or
   git-commit must support more fine-grained control over which hooks
   are executed.
 - `-q`: Hide the fact that we are committing several times by not
   printing the commit summary.
Signed-off-by: Fabian Ruch <bafain@gmail.com>
---
 git-rebase--interactive.sh    | 52 ++++++++++++++++++++++++++++++++++++-------
 t/t3404-rebase-interactive.sh |  8 +++++++
 2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index ea5514e..fffdfa5 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -490,7 +490,42 @@ record_in_rewritten() {
 	esac
 }
 
+# Apply the changes introduced by the given commit to the current head.
+#
+# do_pick [--edit] <commit> <title>
+#
+# Wrapper around git-cherry-pick.
+#
+# <title>
+#     The commit message title of <commit>. Used for information
+#     purposes only.
+#
+# <commit>
+#     The commit to cherry-pick.
+#
+# -e, --edit
+#     After picking <commit>, open an editor and let the user edit the
+#     commit message. The editor contents becomes the commit message of
+#     the new head.
 do_pick () {
+	edit=
+	while test $# -gt 0
+	do
+		case "$1" in
+		-e|--edit)
+			edit=y
+			;;
+		-*)
+			warn "do_pick: ignored option -- $1"
+			;;
+		*)
+			break
+			;;
+		esac
+		shift
+	done
+	test $# -ne 2 && die "do_pick: wrong number of arguments"
+
 	if test "$(git rev-parse HEAD)" = "$squash_onto"
 	then
 		# Set the correct commit message and author info on the
@@ -512,6 +547,14 @@ do_pick () {
 		pick_one $1 ||
 			die_with_patch $1 "Could not apply $1... $2"
 	fi
+
+	if test -n "$edit"
+	then
+		git commit --allow-empty --amend --no-post-rewrite -n -q ${gpg_sign_opt:+"$gpg_sign_opt"} || {
+			warn "Could not amend commit after successfully picking $1... $2"
+			exit_with_patch $1 1
+		}
+	fi
 }
 
 do_next () {
@@ -532,14 +575,7 @@ do_next () {
 		comment_for_reflog reword
 
 		mark_action_done
-		do_pick $sha1 "$rest"
-		git commit --amend --no-post-rewrite ${gpg_sign_opt:+"$gpg_sign_opt"} || {
-			warn "Could not amend commit after successfully picking $sha1... $rest"
-			warn "This is most likely due to an empty commit message, or the pre-commit hook"
-			warn "failed. If the pre-commit hook failed, you may need to resolve the issue before"
-			warn "you are able to reword the commit."
-			exit_with_patch $sha1 1
-		}
+		do_pick --edit $sha1 "$rest"
 		record_in_rewritten $sha1
 		;;
 	edit|e)
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8197ed2..9931143 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -75,6 +75,14 @@ test_expect_success 'rebase --keep-empty' '
 	test_line_count = 6 actual
 '
 
+test_expect_success 'rebase --keep-empty' '
+	git checkout emptybranch &&
+	set_fake_editor &&
+	FAKE_LINES="1 reword 2" git rebase --keep-empty -i HEAD~2 &&
+	git log --oneline >actual &&
+	test_line_count = 6 actual
+'
+
 test_expect_success 'rebase -i with the exec command' '
 	git checkout master &&
 	(
-- 
2.0.0
Previous: Johannes SchindelinNext: Michael Haggerty
Message 7 of 16 in “rebase -i: Make option handling in pick_one more flexible”
  1. 1/7 rebase -i: Make option handling in pick_one more flexibleFabian Ruch, Jun 19, 2014
  2. Michael HaggertyJun 20, 2014
  3. Junio C HamanoJun 20, 2014
  4. Fabian RuchJun 23, 2014
  5. Fabian RuchJun 21, 2014
  6. Johannes SchindelinJun 23, 2014
  7. 2/7 rebase -i: Teach do_pick the option --editFabian Ruch, Jun 19, 2014
  8. Michael HaggertyJun 20, 2014
  9. Fabian RuchJun 22, 2014
  10. 3/7 rebase -i: Stop on root commits with empty log messagesFabian Ruch, Jun 19, 2014
  11. Eric SunshineJun 21, 2014
  12. Fabian RuchJun 22, 2014
  13. 4/7 rebase -i: Commit only once when rewriting picksFabian Ruch, Jun 19, 2014
  14. 5/7 rebase -i: Do not die in do_pickFabian Ruch, Jun 19, 2014
  15. 6/7 rebase -i: Prepare for squash in terms of do_pick --amendFabian Ruch, Jun 19, 2014
  16. 7/7 rebase -i: Teach do_pick the options --amend and --fileFabian Ruch, Jun 19, 2014

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.