rebase -i: fix parsing of "fixup -C<commit>"

If the user omits the space between "-C" and the commit in a fixup command then it is parsed as an ordinary fixup and the commit message is not updated as it should be. Fix this by making the space between "-C" and "<commit>" optional as it is for the "merge" command. Note that set_replace_editor() is changed to set $GIT_SEQUENCE_EDITOR instead of $EDITOR in order to be able to replace the todo list and reword commits with $FAKE_COMMIT_MESSAGE. This is safe as all the existing users are using set_replace_editor() to replace the todo list. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Feb 23, 2023 at 20:55 UTC 666b6e1135c12925efe608c4d5f03234c54e2d0c
4 files changed +42 -6
sequencer.c
+2 -4
@@ -2532,12 +2532,10 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
2532 }
2533
2534 if (item->command == TODO_FIXUP) {
2535 - if (skip_prefix(bol, "-C", &bol) &&
2536 - (*bol == ' ' || *bol == '\t')) {
2535 + if (skip_prefix(bol, "-C", &bol)) {
2536 bol += strspn(bol, " \t");
2537 item->flags |= TODO_REPLACE_FIXUP_MSG;
2539 - } else if (skip_prefix(bol, "-c", &bol) &&
2540 - (*bol == ' ' || *bol == '\t')) {
2538 + } else if (skip_prefix(bol, "-c", &bol)) {
2539 bol += strspn(bol, " \t");
2540 item->flags |= TODO_EDIT_FIXUP_MSG;
2541 }
t/lib-rebase.sh
+6 -2
@@ -211,6 +211,9 @@ check_reworded_commits () {
211 # usage: set_replace_editor <file>
212 #
213 # Replace the todo file with the exact contents of the given file.
214 +# N.B. sets GIT_SEQUENCE_EDITOR rather than EDITOR so it can be
215 +# combined with set_fake_editor to reword commits and replace the
216 +# todo list
217 set_replace_editor () {
218 cat >script <<-\EOF &&
219 cat FILENAME >"$1"
@@ -219,6 +222,7 @@ set_replace_editor () {
222 cat "$1"
223 EOF
224
222 - sed -e "s/FILENAME/$1/g" <script | write_script fake-editor.sh &&
223 - test_set_editor "$(pwd)/fake-editor.sh"
225 + sed -e "s/FILENAME/$1/g" script |
226 + write_script fake-sequence-editor.sh &&
227 + test_set_sequence_editor "$(pwd)/fake-sequence-editor.sh"
228 }
t/t3437-rebase-fixup-options.sh
+26
@@ -50,6 +50,7 @@ test_expect_success 'setup' '
50 body
51 EOF
52
53 + test_commit initial &&
54 test_commit A A &&
55 test_commit B B &&
56 get_author HEAD >expected-author &&
@@ -208,4 +209,29 @@ test_expect_success 'fixup -C works upon --autosquash with amend!' '
209 actual-squash-message
210 '
211
212 +test_expect_success 'fixup -[Cc]<commit> works' '
213 + test_when_finished "test_might_fail git rebase --abort" &&
214 + cat >todo <<-\EOF &&
215 + pick A
216 + fixup -CA1
217 + pick B
218 + fixup -cA2
219 + EOF
220 + (
221 + set_replace_editor todo &&
222 + FAKE_COMMIT_MESSAGE="edited and fixed up" \
223 + git rebase -i initial initial
224 + ) &&
225 + git log --pretty=format:%B initial.. >actual &&
226 + cat >expect <<-EOF &&
227 + edited and fixed up
228 + $EMPTY
229 + new subject
230 + $EMPTY
231 + new
232 + body
233 + EOF
234 + test_cmp expect actual
235 +'
236 +
237 test_done
t/test-lib-functions.sh
+8
@@ -32,6 +32,14 @@ test_set_editor () {
32 export EDITOR
33 }
34
35 +# Like test_set_editor but sets GIT_SEQUENCE_EDITOR instead of EDITOR
36 +test_set_sequence_editor () {
37 + FAKE_SEQUENCE_EDITOR="$1"
38 + export FAKE_SEQUENCE_EDITOR
39 + GIT_SEQUENCE_EDITOR='"$FAKE_SEQUENCE_EDITOR"'
40 + export GIT_SEQUENCE_EDITOR
41 +}
42 +
43 test_decode_color () {
44 awk '
45 function name(n) {