From: "Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Stefan Haller" <lists@haller-berlin.de>,
"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
"Patrick Steinhardt" <ps@pks.im>,
"Rubén Justo" <rjusto@gmail.com>,
"Phillip Wood" <phillip.wood123@gmail.com>,
"Phillip Wood" <phillip.wood@dunelm.org.uk>
Subject: [PATCH v3 0/2] rebase -i: improve error message when picking merge
Date: Thu, 30 May 2024 13:43:48 +0000 [thread overview]
Message-ID: <pull.1672.v3.git.1717076630.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1672.v2.git.1712585787.gitgitgadget@gmail.com>
If the user tries to pick a merge commit error out when parsing the todo
list rather than complaining when trying to pick the commit.
Sorry for the delay in re-rolling, thanks to Junio and Patrick for their
comments on V2. I've rebased on to master to avoid a conflict with
'ps/the-index-is-no-more' and updated patch 2 to
* Add advice on how rebase a merge commit as suggested by Junio. To avoid
duplication between the error messages and the advice I've shortened the
error messages.
* Rework the control flow to make it easier to extend checks on merge
commits if new commands are added in the future as suggested by Junio
Phillip Wood (2):
rebase -i: pass struct replay_opts to parse_insn_line()
rebase -i: improve error message when picking merge
Documentation/config/advice.txt | 2 +
advice.c | 1 +
advice.h | 1 +
builtin/rebase.c | 17 ++++---
rebase-interactive.c | 21 +++++----
rebase-interactive.h | 9 ++--
sequencer.c | 83 ++++++++++++++++++++++++++++-----
sequencer.h | 4 +-
t/t3404-rebase-interactive.sh | 45 ++++++++++++++++++
9 files changed, 153 insertions(+), 30 deletions(-)
base-commit: 3a57aa566a21e7a510c64881bc6bdff7eb397988
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1672%2Fphillipwood%2Frebase-reject-merges-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1672/phillipwood/rebase-reject-merges-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/1672
Range-diff vs v2:
1: 1bcf92c6105 ! 1: 91c6f2f1b45 rebase -i: pass struct replay_opts to parse_insn_line()
@@ builtin/rebase.c: static int edit_todo_file(unsigned flags)
@@ builtin/rebase.c: static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
error(_("could not generate todo list"));
else {
- discard_index(&the_index);
+ discard_index(the_repository->index);
- if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
- &todo_list))
+ if (todo_list_parse_insn_buffer(the_repository, &replay,
2: fbc6746e018 ! 2: 86052416b22 rebase -i: improve error message when picking merge
@@ Commit message
pass "-m". For users who are rebasing the message is confusing as there
is no way for rebase to cherry-pick the merge.
- Improve the user experience by detecting the error when the todo list is
- parsed rather than waiting for the "pick" command to fail and print a
- message recommending the "merge" command instead. We recommend "merge"
- rather than "exec git cherry-pick -m ..." on the assumption that
- cherry-picking merges is relatively rare and it is more likely that the
- user chose "pick" by a mistake.
+ Improve the user experience by detecting the error and printing some
+ advice on how to fix it when the todo list is parsed rather than waiting
+ for the "pick" command to fail. The advice recommends "merge" rather
+ than "exec git cherry-pick -m ..." on the assumption that cherry-picking
+ merges is relatively rare and it is more likely that the user chose
+ "pick" by a mistake.
It would be possible to support cherry-picking merges by allowing the
user to pass "-m" to "pick" commands but that adds complexity to do
@@ Commit message
Reported-by: Stefan Haller <lists@haller-berlin.de>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
+ ## Documentation/config/advice.txt ##
+@@ Documentation/config/advice.txt: advice.*::
+ `pushNonFFCurrent`, `pushNonFFMatching`, `pushAlreadyExists`,
+ `pushFetchFirst`, `pushNeedsForce`, and `pushRefNeedsUpdate`
+ simultaneously.
++ rebaseTodoError::
++ Shown when there is an error after editing the rebase todo list.
+ refSyntax::
+ Shown when the user provides an illegal ref name, to
+ tell the user about the ref syntax documentation.
+
+ ## advice.c ##
+@@ advice.c: static struct {
+ [ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName" },
+ [ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected" },
+ [ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward" }, /* backwards compatibility */
++ [ADVICE_REBASE_TODO_ERROR] = { "rebaseTodoError" },
+ [ADVICE_REF_SYNTAX] = { "refSyntax" },
+ [ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh" },
+ [ADVICE_RESOLVE_CONFLICT] = { "resolveConflict" },
+
+ ## advice.h ##
+@@ advice.h: enum advice_type {
+ ADVICE_PUSH_UNQUALIFIED_REF_NAME,
+ ADVICE_PUSH_UPDATE_REJECTED,
+ ADVICE_PUSH_UPDATE_REJECTED_ALIAS,
++ ADVICE_REBASE_TODO_ERROR,
+ ADVICE_REF_SYNTAX,
+ ADVICE_RESET_NO_REFRESH_WARNING,
+ ADVICE_RESOLVE_CONFLICT,
+
## sequencer.c ##
@@ sequencer.c: static int check_label_or_ref_arg(enum todo_command command, const char *arg)
return 0;
}
-static int parse_insn_line(struct repository *r, struct replay_opts *opts UNUSED,
-+static int error_merge_commit(enum todo_command command)
++static int check_merge_commit_insn(enum todo_command command)
+{
+ switch(command) {
+ case TODO_PICK:
-+ return error(_("'%s' does not accept merge commits, "
-+ "please use '%s'"),
-+ todo_command_info[command].str, "merge -C");
++ error(_("'%s' does not accept merge commits"),
++ todo_command_info[command].str);
++ advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(
++ /*
++ * TRANSLATORS: 'pick' and 'merge -C' should not be
++ * translated.
++ */
++ "'pick' does not take a merge commit. If you wanted to\n"
++ "replay the merge, use 'merge -C' on the commit."));
++ return -1;
+
+ case TODO_REWORD:
-+ return error(_("'%s' does not accept merge commits, "
-+ "please use '%s'"),
-+ todo_command_info[command].str, "merge -c");
++ error(_("'%s' does not accept merge commits"),
++ todo_command_info[command].str);
++ advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(
++ /*
++ * TRANSLATORS: 'reword' and 'merge -c' should not be
++ * translated.
++ */
++ "'reword' does not take a merge commit. If you wanted to\n"
++ "replay the merge and reword the commit message, use\n"
++ "'merge -c' on the commit"));
++ return -1;
+
+ case TODO_EDIT:
-+ return error(_("'%s' does not accept merge commits, "
-+ "please use '%s' followed by '%s'"),
-+ todo_command_info[command].str,
-+ "merge -C", "break");
++ error(_("'%s' does not accept merge commits"),
++ todo_command_info[command].str);
++ advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(
++ /*
++ * TRANSLATORS: 'edit', 'merge -C' and 'break' should
++ * not be translated.
++ */
++ "'edit' does not take a merge commit. If you wanted to\n"
++ "replay the merge, use 'merge -C' on the commit, and then\n"
++ "'break' to give the control back to you so that you can\n"
++ "do 'git commit --amend && git rebase --continue'."));
++ return -1;
+
+ case TODO_FIXUP:
+ case TODO_SQUASH:
+ return error(_("cannot squash merge commit into another commit"));
+
++ case TODO_MERGE:
++ return 0;
++
+ default:
+ BUG("unexpected todo_command");
+ }
@@ sequencer.c: static int parse_insn_line(struct repository *r, struct replay_opts
- return item->commit ? 0 : -1;
+ if (!item->commit)
+ return -1;
-+ if (is_rebase_i(opts) && item->command != TODO_MERGE &&
++ if (is_rebase_i(opts) &&
+ item->commit->parents && item->commit->parents->next)
-+ return error_merge_commit(item->command);
++ return check_merge_commit_insn(item->command);
+ return 0;
}
@@ t/t3404-rebase-interactive.sh: test_expect_success 'bad labels and refs rejected
+ test_must_fail git rebase -i HEAD 2>actual
+ ) &&
+ cat >expect <<-EOF &&
-+ error: ${SQ}pick${SQ} does not accept merge commits, please use ${SQ}merge -C${SQ}
++ error: ${SQ}pick${SQ} does not accept merge commits
++ hint: ${SQ}pick${SQ} does not take a merge commit. If you wanted to
++ hint: replay the merge, use ${SQ}merge -C${SQ} on the commit.
++ hint: Disable this message with "git config advice.rebaseTodoError false"
+ error: invalid line 1: pick $oid
-+ error: ${SQ}reword${SQ} does not accept merge commits, please use ${SQ}merge -c${SQ}
++ error: ${SQ}reword${SQ} does not accept merge commits
++ hint: ${SQ}reword${SQ} does not take a merge commit. If you wanted to
++ hint: replay the merge and reword the commit message, use
++ hint: ${SQ}merge -c${SQ} on the commit
++ hint: Disable this message with "git config advice.rebaseTodoError false"
+ error: invalid line 2: reword $oid
-+ error: ${SQ}edit${SQ} does not accept merge commits, please use ${SQ}merge -C${SQ} followed by ${SQ}break${SQ}
++ error: ${SQ}edit${SQ} does not accept merge commits
++ hint: ${SQ}edit${SQ} does not take a merge commit. If you wanted to
++ hint: replay the merge, use ${SQ}merge -C${SQ} on the commit, and then
++ hint: ${SQ}break${SQ} to give the control back to you so that you can
++ hint: do ${SQ}git commit --amend && git rebase --continue${SQ}.
++ hint: Disable this message with "git config advice.rebaseTodoError false"
+ error: invalid line 3: edit $oid
+ error: cannot squash merge commit into another commit
+ error: invalid line 4: fixup $oid
--
gitgitgadget
next prev parent reply other threads:[~2024-05-30 13:43 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-26 10:58 [PATCH] rebase -i: improve error message when picking merge Phillip Wood via GitGitGadget
2024-04-03 13:42 ` phillip.wood123
2024-04-04 6:08 ` Patrick Steinhardt
2024-04-04 6:08 ` Patrick Steinhardt
2024-04-04 15:29 ` phillip.wood123
2024-04-04 19:44 ` Rubén Justo
2024-04-05 9:30 ` phillip.wood123
2024-04-06 14:24 ` Rubén Justo
2024-04-07 13:55 ` phillip.wood123
2024-04-08 14:16 ` [PATCH v2 0/2] " Phillip Wood via GitGitGadget
2024-04-08 14:16 ` [PATCH v2 1/2] rebase -i: pass struct replay_opts to parse_insn_line() Phillip Wood via GitGitGadget
2024-04-09 4:03 ` Patrick Steinhardt
2024-04-08 14:16 ` [PATCH v2 2/2] rebase -i: improve error message when picking merge Phillip Wood via GitGitGadget
2024-04-08 22:29 ` Junio C Hamano
2024-04-09 4:03 ` Patrick Steinhardt
2024-04-09 5:08 ` Junio C Hamano
2024-04-09 6:04 ` Patrick Steinhardt
2024-04-09 15:04 ` Phillip Wood
2024-04-09 19:56 ` Junio C Hamano
2024-04-12 13:24 ` Phillip Wood
2024-05-30 13:43 ` Phillip Wood via GitGitGadget [this message]
2024-05-30 13:43 ` [PATCH v3 1/2] rebase -i: pass struct replay_opts to parse_insn_line() Phillip Wood via GitGitGadget
2024-05-30 13:43 ` [PATCH v3 2/2] rebase -i: improve error message when picking merge Phillip Wood via GitGitGadget
2024-05-30 17:09 ` [PATCH v3 0/2] " Junio C Hamano
2024-06-03 9:22 ` Phillip Wood
2024-06-03 15:42 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1672.v3.git.1717076630.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=lists@haller-berlin.de \
--cc=phillip.wood123@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ps@pks.im \
--cc=rjusto@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).