rebase -i: teach --autosquash to work with amend!

If the commit subject starts with "amend!" then rearrange it like a "fixup!" commit and replace `pick` command with `fixup -C` command, which is used to fixup up the content if any and replaces the original commit message with amend! commit's message. Original-patch-by: Phillip Wood <phillip.wood@dunelm.org.uk> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Charvi Mendiratta <charvi077@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Charvi Mendiratta committed Jan 29, 2021 at 23:50 UTC bae5b4aea523388faedd3b850c862fe45198c6b2
2 files changed +28 -7
sequencer.c
+16 -7
@@ -5662,6 +5662,12 @@ static int subject2item_cmp(const void *fndata,
5662
5663 define_commit_slab(commit_todo_item, struct todo_item *);
5664
5665 +static inline int skip_fixup_amend_squash(const char *subject, const char **p) {
5666 + return skip_prefix(subject, "fixup! ", p) ||
5667 + skip_prefix(subject, "amend! ", p) ||
5668 + skip_prefix(subject, "squash! ", p);
5669 +}
5670 +
5671 /*
5672 * Rearrange the todo list that has both "pick commit-id msg" and "pick
5673 * commit-id fixup!/squash! msg" in it so that the latter is put immediately
@@ -5720,15 +5726,13 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
5726 format_subject(&buf, subject, " ");
5727 subject = subjects[i] = strbuf_detach(&buf, &subject_len);
5728 unuse_commit_buffer(item->commit, commit_buffer);
5723 - if ((skip_prefix(subject, "fixup! ", &p) ||
5724 - skip_prefix(subject, "squash! ", &p))) {
5729 + if (skip_fixup_amend_squash(subject, &p)) {
5730 struct commit *commit2;
5731
5732 for (;;) {
5733 while (isspace(*p))
5734 p++;
5730 - if (!skip_prefix(p, "fixup! ", &p) &&
5731 - !skip_prefix(p, "squash! ", &p))
5735 + if (!skip_fixup_amend_squash(p, &p))
5736 break;
5737 }
5738
@@ -5758,9 +5762,14 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
5762 }
5763 if (i2 >= 0) {
5764 rearranged = 1;
5761 - todo_list->items[i].command =
5762 - starts_with(subject, "fixup!") ?
5763 - TODO_FIXUP : TODO_SQUASH;
5765 + if (starts_with(subject, "fixup!")) {
5766 + todo_list->items[i].command = TODO_FIXUP;
5767 + } else if (starts_with(subject, "amend!")) {
5768 + todo_list->items[i].command = TODO_FIXUP;
5769 + todo_list->items[i].flags = TODO_REPLACE_FIXUP_MSG;
5770 + } else {
5771 + todo_list->items[i].command = TODO_SQUASH;
5772 + }
5773 if (tail[i2] < 0) {
5774 next[i] = next[i2];
5775 next[i2] = i;
t/t3437-rebase-fixup-options.sh
+12
@@ -210,4 +210,16 @@ test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
210 test_cmp_rev HEAD^ A
211 '
212
213 +test_expect_success 'fixup -C works upon --autosquash with amend!' '
214 + git checkout --detach branch &&
215 + FAKE_COMMIT_AMEND=squashed \
216 + FAKE_MESSAGE_COPY=actual-squash-message \
217 + git -c commit.status=false rebase -ik --autosquash \
218 + --signoff A &&
219 + git diff-tree --exit-code --patch HEAD branch -- &&
220 + test_cmp_rev HEAD^ A &&
221 + test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
222 + actual-squash-message
223 +'
224 +
225 test_done