diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt index f833411653..0e35ae5240 100644 --- a/Documentation/config/advice.txt +++ b/Documentation/config/advice.txt @@ -56,6 +56,8 @@ advice.*:: Shown when the user's information is guessed from the system username and domain name, to tell the user how to set their identity configuration. + mergeConflict:: + Shown when various commands stop because of conflicts. nestedTag:: Shown when a user attempts to recursively tag a tag object. pushAlreadyExists:: diff --git a/advice.c b/advice.c index b0e0550687..d19648b7f8 100644 --- a/advice.c +++ b/advice.c @@ -57,6 +57,7 @@ static struct { [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" }, [ADVICE_IGNORED_HOOK] = { "ignoredHook" }, [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity" }, + [ADVICE_MERGE_CONFLICT] = { "mergeConflict" }, [ADVICE_NESTED_TAG] = { "nestedTag" }, [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning" }, [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists" }, diff --git a/advice.h b/advice.h index bf630ee3ac..c8d29f97f3 100644 --- a/advice.h +++ b/advice.h @@ -25,6 +25,7 @@ enum advice_type { ADVICE_GRAFT_FILE_DEPRECATED, ADVICE_IGNORED_HOOK, ADVICE_IMPLICIT_IDENTITY, + ADVICE_MERGE_CONFLICT, ADVICE_NESTED_TAG, ADVICE_OBJECT_NAME_WARNING, ADVICE_PUSH_ALREADY_EXISTS, diff --git a/builtin/am.c b/builtin/am.c index e8fb27a8ef..ff8e9db089 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state) static void NORETURN die_user_resolve(const struct am_state *state) { if (state->resolvemsg) { - printf_ln("%s", state->resolvemsg); + advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", state->resolvemsg); } else { const char *cmdline = state->interactive ? "git am -i" : "git am"; + struct strbuf sb = STRBUF_INIT; - printf_ln(_("When you have resolved this problem, run \"%s --continue\"."), cmdline); - printf_ln(_("If you prefer to skip this patch, run \"%s --skip\" instead."), cmdline); + strbuf_addf(&sb, _("When you have resolved this problem, run \"%s --continue\".\n"), cmdline); + strbuf_addf(&sb, _("If you prefer to skip this patch, run \"%s --skip\" instead.\n"), cmdline); if (advice_enabled(ADVICE_AM_WORK_DIR) && is_empty_or_missing_file(am_path(state, "patch")) && !repo_index_has_changes(the_repository, NULL, NULL)) - printf_ln(_("To record the empty patch as an empty commit, run \"%s --allow-empty\"."), cmdline); + strbuf_addf(&sb, _("To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"), cmdline); - printf_ln(_("To restore the original branch and stop patching, run \"%s --abort\"."), cmdline); + strbuf_addf(&sb, _("To restore the original branch and stop patching, run \"%s --abort\"."), cmdline); + + advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", sb.buf); + strbuf_release(&sb); } exit(128); diff --git a/sequencer.c b/sequencer.c index 4e14fa6541..f4e6284a6c 100644 --- a/sequencer.c +++ b/sequencer.c @@ -479,7 +479,7 @@ static void print_advice(struct repository *r, int show_hint, msg = getenv("GIT_CHERRY_PICK_HELP"); if (msg) { - advise("%s\n", msg); + advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", msg); /* * A conflict has occurred but the porcelain * (typically rebase --interactive) wants to take care @@ -492,22 +492,25 @@ static void print_advice(struct repository *r, int show_hint, if (show_hint) { if (opts->no_commit) - advise(_("after resolving the conflicts, mark the corrected paths\n" - "with 'git add ' or 'git rm '")); + advise_if_enabled(ADVICE_MERGE_CONFLICT, + _("after resolving the conflicts, mark the corrected paths\n" + "with 'git add ' or 'git rm '")); else if (opts->action == REPLAY_PICK) - advise(_("After resolving the conflicts, mark them with\n" - "\"git add/rm \", then run\n" - "\"git cherry-pick --continue\".\n" - "You can instead skip this commit with \"git cherry-pick --skip\".\n" - "To abort and get back to the state before \"git cherry-pick\",\n" - "run \"git cherry-pick --abort\".")); + advise_if_enabled(ADVICE_MERGE_CONFLICT, + _("After resolving the conflicts, mark them with\n" + "\"git add/rm \", then run\n" + "\"git cherry-pick --continue\".\n" + "You can instead skip this commit with \"git cherry-pick --skip\".\n" + "To abort and get back to the state before \"git cherry-pick\",\n" + "run \"git cherry-pick --abort\".")); else if (opts->action == REPLAY_REVERT) - advise(_("After resolving the conflicts, mark them with\n" - "\"git add/rm \", then run\n" - "\"git revert --continue\".\n" - "You can instead skip this commit with \"git revert --skip\".\n" - "To abort and get back to the state before \"git revert\",\n" - "run \"git revert --abort\".")); + advise_if_enabled(ADVICE_MERGE_CONFLICT, + _("After resolving the conflicts, mark them with\n" + "\"git add/rm \", then run\n" + "\"git revert --continue\".\n" + "You can instead skip this commit with \"git revert --skip\".\n" + "To abort and get back to the state before \"git revert\",\n" + "run \"git revert --abort\".")); else BUG("unexpected pick action in print_advice()"); } diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index aeab689a98..43c579ea53 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' ' hint: You can instead skip this commit with "git revert --skip". hint: To abort and get back to the state before "git revert", hint: run "git revert --abort". + hint: Disable this message with "git config advice.mergeConflict false" EOF test_commit --append --no-tag "double-add dream" dream dream && test_must_fail git revert HEAD^ 2>actual && diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index c88d597b12..f3947b400a 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' ' hint: You can instead skip this commit with "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort". + hint: Disable this message with "git config advice.mergeConflict false" EOF test_must_fail git cherry-pick picked 2>actual && @@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' " error: could not apply \$picked... picked hint: after resolving the conflicts, mark the corrected paths hint: with 'git add ' or 'git rm ' + hint: Disable this message with \"git config advice.mergeConflict false\" EOF test_must_fail git cherry-pick --no-commit picked 2>actual && diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 3b12576269..5e2b6c80ea 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -1224,8 +1224,8 @@ test_expect_success 'record as an empty commit when meeting e-mail message that test_expect_success 'skip an empty patch in the middle of an am session' ' git checkout empty-commit^ && - test_must_fail git am empty-commit.patch >err && - grep "Patch is empty." err && + test_must_fail git am empty-commit.patch >out 2>err && + grep "Patch is empty." out && grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err && git am --skip && test_path_is_missing .git/rebase-apply && @@ -1236,8 +1236,8 @@ test_expect_success 'skip an empty patch in the middle of an am session' ' test_expect_success 'record an empty patch as an empty commit in the middle of an am session' ' git checkout empty-commit^ && - test_must_fail git am empty-commit.patch >err && - grep "Patch is empty." err && + test_must_fail git am empty-commit.patch >out 2>err && + grep "Patch is empty." out && grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err && git am --allow-empty >output && grep "No changes - recorded it as an empty commit." output && diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh index 45f1d4f95e..661feb6070 100755 --- a/t/t4254-am-corrupt.sh +++ b/t/t4254-am-corrupt.sh @@ -59,7 +59,7 @@ test_expect_success setup ' # Also, it had the unwanted side-effect of deleting f. test_expect_success 'try to apply corrupted patch' ' test_when_finished "git am --abort" && - test_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual && + test_must_fail git -c advice.amWorkDir=false -c advice.mergeConflict=false am bad-patch.diff 2>actual && echo "error: git diff header lacks filename information (line 4)" >expected && test_path_is_file f && test_cmp expected actual