From: ZheNing Hu <adlternative@xxxxxxxxx> In the past, git cherry-pick would print such advice when there was a conflict: hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: and commit the result with 'git commit' But in fact, when we want to cherry-pick multiple commits, we should not use "git commit" after resolving conflicts, which will make Git generate some errors. We should recommend users to use `git cherry-pick --continue`, `git cherry-pick --abort`, just like git rebase does. This is the improved advice: hint: Resolve all conflicts manually, mark them as resolved with hint: "git add/rm <conflicted_files>", then run "git cherry-pick \ --continue". hint: You can instead skip this commit: run "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort". Mentored-by: Christian Couder <christian.couder@xxxxxxxxx> Mentored-by Hariom Verma <hariom18599@xxxxxxxxx>: Helped-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> Hepled-by: Junio C Hamano <gitster@xxxxxxxxx> Signed-off-by: ZheNing Hu <adlternative@xxxxxxxxx> --- sequencer.c | 19 ++++++++++++++----- t/t3507-cherry-pick-conflict.sh | 23 +++++++++++++++-------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/sequencer.c b/sequencer.c index ceaf73a34df..b9adeb7e5f5 100644 --- a/sequencer.c +++ b/sequencer.c @@ -39,6 +39,16 @@ static const char sign_off_header[] = "Signed-off-by: "; static const char cherry_picked_prefix[] = "(cherry picked from commit "; +static const char *no_commit_advice = N_("after resolving the conflicts, mark the corrected paths\n" + "with 'git add <paths>' or 'git rm <paths>'"); +static const char *commit_advice = N_("after resolving the conflicts, mark the corrected paths\n" + "with 'git add <paths>' or 'git rm <paths>'\n" + "and commit the result with 'git commit'"); +static const char *cherry_pick_advice = N_("Resolve all conflicts manually, mark them as resolved with\n" + "\"git add/rm <conflicted_files>\", then run \"git cherry-pick --continue\".\n" + "You can instead skip this commit: run \"git cherry-pick --skip\".\n" + "To abort and get back to the state before \"git cherry-pick\",\n" + "run \"git cherry-pick --abort\"."); GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG") @@ -419,12 +429,9 @@ static void print_advice(struct replay_opts *opts, const char *help_msgs) if (help_msgs) advise("%s\n", help_msgs); else if (opts->no_commit) - advise(_("after resolving the conflicts, mark the corrected paths\n" - "with 'git add <paths>' or 'git rm <paths>'")); + advise("%s\n", _(no_commit_advice)); else - advise(_("after resolving the conflicts, mark the corrected paths\n" - "with 'git add <paths>' or 'git rm <paths>'\n" - "and commit the result with 'git commit'")); + advise("%s\n", _(commit_advice)); } static int write_message(const void *buf, size_t len, const char *filename, @@ -2269,6 +2276,8 @@ static int do_pick_commit(struct repository *r, ? _("could not revert %s... %s") : _("could not apply %s... %s"), short_commit_name(commit), msg.subject); + if (opts->action == REPLAY_PICK) + help_msgs = _(cherry_pick_advice); if (((opts->action == REPLAY_PICK && !opts->rebase_preserve_merges_mode) || (help_msgs = check_need_delete_cherry_pick_head(r))) && diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 6f8035399d9..bf77bb0bd50 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -53,9 +53,11 @@ test_expect_success 'advice from failed cherry-pick' " picked=\$(git rev-parse --short picked) && cat <<-EOF >expected && error: could not apply \$picked... picked - hint: after resolving the conflicts, mark the corrected paths - hint: with 'git add <paths>' or 'git rm <paths>' - hint: and commit the result with 'git commit' + hint: Resolve all conflicts manually, mark them as resolved with + hint: \"git add/rm <conflicted_files>\", then run \"git cherry-pick --continue\". + hint: You can instead skip this commit: run \"git cherry-pick --skip\". + hint: To abort and get back to the state before \"git cherry-pick\", + hint: run \"git cherry-pick --abort\". EOF test_must_fail git cherry-pick picked 2>actual && @@ -68,8 +70,11 @@ test_expect_success 'advice from failed cherry-pick --no-commit' " picked=\$(git rev-parse --short picked) && cat <<-EOF >expected && error: could not apply \$picked... picked - hint: after resolving the conflicts, mark the corrected paths - hint: with 'git add <paths>' or 'git rm <paths>' + hint: Resolve all conflicts manually, mark them as resolved with + hint: \"git add/rm <conflicted_files>\", then run \"git cherry-pick --continue\". + hint: You can instead skip this commit: run \"git cherry-pick --skip\". + hint: To abort and get back to the state before \"git cherry-pick\", + hint: run \"git cherry-pick --abort\". EOF test_must_fail git cherry-pick --no-commit picked 2>actual && @@ -82,9 +87,11 @@ test_expect_success 'advice from failed cherry-pick with GIT_CHERRY_PICK_HELP' " picked=\$(git rev-parse --short picked) && cat <<-EOF >expected && error: could not apply \$picked... picked - hint: after resolving the conflicts, mark the corrected paths - hint: with 'git add <paths>' or 'git rm <paths>' - hint: and commit the result with 'git commit' + hint: Resolve all conflicts manually, mark them as resolved with + hint: \"git add/rm <conflicted_files>\", then run \"git cherry-pick --continue\". + hint: You can instead skip this commit: run \"git cherry-pick --skip\". + hint: To abort and get back to the state before \"git cherry-pick\", + hint: run \"git cherry-pick --abort\". EOF GIT_CHERRY_PICK_HELP='and then do something else' && export GIT_CHERRY_PICK_HELP && -- gitgitgadget