sequencer: allow disabling conflict advice

Allow disabling the advice shown when a squencer operation results in a merge conflict through a new config 'advice.mergeConflict', which is named generically such that it can be used by other commands eventually. Remove that final '\n' in the first hunk in sequencer.c to avoid an otherwise empty 'hint: ' line before the line 'hint: Disable this message with "git config advice.mergeConflict false"' which is automatically added by 'advise_if_enabled'. Note that we use 'advise_if_enabled' for each message in the second hunk in sequencer.c, instead of using 'if (show_hints && advice_enabled(...)', because the former instructs the user how to disable the advice, which is more user-friendly. Update the tests accordingly. Note that the body of the second test in t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must escape them in the added line. Note that t5520-pull.sh, which checks that we display the advice for 'git rebase' (via 'git pull --rebase') does not have to be updated because it only greps for a specific line in the advice message. Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Philippe Blain committed Mar 16, 2024 at 21:16 UTC ec0300914b42277077f51a8c7e3438d7565eb261
6 files changed +25 -15
Documentation/config/advice.txt
+2
@@ -56,6 +56,8 @@ advice.*::
56 Shown when the user's information is guessed from the
57 system username and domain name, to tell the user how to
58 set their identity configuration.
59 + mergeConflict::
60 + Shown when various commands stop because of conflicts.
61 nestedTag::
62 Shown when a user attempts to recursively tag a tag object.
63 pushAlreadyExists::
advice.c
+1
@@ -57,6 +57,7 @@ static struct {
57 [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" },
58 [ADVICE_IGNORED_HOOK] = { "ignoredHook" },
59 [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity" },
60 + [ADVICE_MERGE_CONFLICT] = { "mergeConflict" },
61 [ADVICE_NESTED_TAG] = { "nestedTag" },
62 [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning" },
63 [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists" },
advice.h
+1
@@ -25,6 +25,7 @@ enum advice_type {
25 ADVICE_GRAFT_FILE_DEPRECATED,
26 ADVICE_IGNORED_HOOK,
27 ADVICE_IMPLICIT_IDENTITY,
28 + ADVICE_MERGE_CONFLICT,
29 ADVICE_NESTED_TAG,
30 ADVICE_OBJECT_NAME_WARNING,
31 ADVICE_PUSH_ALREADY_EXISTS,
sequencer.c
+18 -15
@@ -467,7 +467,7 @@ static void print_advice(struct repository *r, int show_hint,
467 char *msg = getenv("GIT_CHERRY_PICK_HELP");
468
469 if (msg) {
470 - advise("%s\n", msg);
470 + advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", msg);
471 /*
472 * A conflict has occurred but the porcelain
473 * (typically rebase --interactive) wants to take care
@@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,
480
481 if (show_hint) {
482 if (opts->no_commit)
483 - advise(_("after resolving the conflicts, mark the corrected paths\n"
484 - "with 'git add <paths>' or 'git rm <paths>'"));
483 + advise_if_enabled(ADVICE_MERGE_CONFLICT,
484 + _("after resolving the conflicts, mark the corrected paths\n"
485 + "with 'git add <paths>' or 'git rm <paths>'"));
486 else if (opts->action == REPLAY_PICK)
486 - advise(_("After resolving the conflicts, mark them with\n"
487 - "\"git add/rm <pathspec>\", then run\n"
488 - "\"git cherry-pick --continue\".\n"
489 - "You can instead skip this commit with \"git cherry-pick --skip\".\n"
490 - "To abort and get back to the state before \"git cherry-pick\",\n"
491 - "run \"git cherry-pick --abort\"."));
487 + advise_if_enabled(ADVICE_MERGE_CONFLICT,
488 + _("After resolving the conflicts, mark them with\n"
489 + "\"git add/rm <pathspec>\", then run\n"
490 + "\"git cherry-pick --continue\".\n"
491 + "You can instead skip this commit with \"git cherry-pick --skip\".\n"
492 + "To abort and get back to the state before \"git cherry-pick\",\n"
493 + "run \"git cherry-pick --abort\"."));
494 else if (opts->action == REPLAY_REVERT)
493 - advise(_("After resolving the conflicts, mark them with\n"
494 - "\"git add/rm <pathspec>\", then run\n"
495 - "\"git revert --continue\".\n"
496 - "You can instead skip this commit with \"git revert --skip\".\n"
497 - "To abort and get back to the state before \"git revert\",\n"
498 - "run \"git revert --abort\"."));
495 + advise_if_enabled(ADVICE_MERGE_CONFLICT,
496 + _("After resolving the conflicts, mark them with\n"
497 + "\"git add/rm <pathspec>\", then run\n"
498 + "\"git revert --continue\".\n"
499 + "You can instead skip this commit with \"git revert --skip\".\n"
500 + "To abort and get back to the state before \"git revert\",\n"
501 + "run \"git revert --abort\"."));
502 else
503 BUG("unexpected pick action in print_advice()");
504 }
t/t3501-revert-cherry-pick.sh
+1
@@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '
170 hint: You can instead skip this commit with "git revert --skip".
171 hint: To abort and get back to the state before "git revert",
172 hint: run "git revert --abort".
173 + hint: Disable this message with "git config advice.mergeConflict false"
174 EOF
175 test_commit --append --no-tag "double-add dream" dream dream &&
176 test_must_fail git revert HEAD^ 2>actual &&
t/t3507-cherry-pick-conflict.sh
+2
@@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' '
60 hint: You can instead skip this commit with "git cherry-pick --skip".
61 hint: To abort and get back to the state before "git cherry-pick",
62 hint: run "git cherry-pick --abort".
63 + hint: Disable this message with "git config advice.mergeConflict false"
64 EOF
65 test_must_fail git cherry-pick picked 2>actual &&
66
@@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' "
75 error: could not apply \$picked... picked
76 hint: after resolving the conflicts, mark the corrected paths
77 hint: with 'git add <paths>' or 'git rm <paths>'
78 + hint: Disable this message with \"git config advice.mergeConflict false\"
79 EOF
80 test_must_fail git cherry-pick --no-commit picked 2>actual &&
81