1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-10 11:56:09 +02:00

Merge branch 'pb/advice-merge-conflict' into next

Hints that suggest what to do after resolving conflicts can now be
squelched by disabling advice.mergeConflict.

Acked-by: Phillip Wood <phillip.wood123@gmail.com>
cf. <e040c631-42d9-4501-a7b8-046f8dac6309@gmail.com>

* pb/advice-merge-conflict:
  builtin/am: allow disabling conflict advice
  sequencer: allow disabling conflict advice
This commit is contained in:
Junio C Hamano 2024-03-25 16:26:50 -07:00
commit 4414e31d81
9 changed files with 39 additions and 25 deletions

View File

@ -56,6 +56,8 @@ advice.*::
Shown when the user's information is guessed from the Shown when the user's information is guessed from the
system username and domain name, to tell the user how to system username and domain name, to tell the user how to
set their identity configuration. set their identity configuration.
mergeConflict::
Shown when various commands stop because of conflicts.
nestedTag:: nestedTag::
Shown when a user attempts to recursively tag a tag object. Shown when a user attempts to recursively tag a tag object.
pushAlreadyExists:: pushAlreadyExists::

View File

@ -57,6 +57,7 @@ static struct {
[ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" }, [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" },
[ADVICE_IGNORED_HOOK] = { "ignoredHook" }, [ADVICE_IGNORED_HOOK] = { "ignoredHook" },
[ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity" }, [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity" },
[ADVICE_MERGE_CONFLICT] = { "mergeConflict" },
[ADVICE_NESTED_TAG] = { "nestedTag" }, [ADVICE_NESTED_TAG] = { "nestedTag" },
[ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning" }, [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning" },
[ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists" }, [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists" },

View File

@ -25,6 +25,7 @@ enum advice_type {
ADVICE_GRAFT_FILE_DEPRECATED, ADVICE_GRAFT_FILE_DEPRECATED,
ADVICE_IGNORED_HOOK, ADVICE_IGNORED_HOOK,
ADVICE_IMPLICIT_IDENTITY, ADVICE_IMPLICIT_IDENTITY,
ADVICE_MERGE_CONFLICT,
ADVICE_NESTED_TAG, ADVICE_NESTED_TAG,
ADVICE_OBJECT_NAME_WARNING, ADVICE_OBJECT_NAME_WARNING,
ADVICE_PUSH_ALREADY_EXISTS, ADVICE_PUSH_ALREADY_EXISTS,

View File

@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)
static void NORETURN die_user_resolve(const struct am_state *state) static void NORETURN die_user_resolve(const struct am_state *state)
{ {
if (state->resolvemsg) { if (state->resolvemsg) {
printf_ln("%s", state->resolvemsg); advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", state->resolvemsg);
} else { } else {
const char *cmdline = state->interactive ? "git am -i" : "git am"; 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); strbuf_addf(&sb, _("When you have resolved this problem, run \"%s --continue\".\n"), cmdline);
printf_ln(_("If you prefer to skip this patch, run \"%s --skip\" instead."), cmdline); strbuf_addf(&sb, _("If you prefer to skip this patch, run \"%s --skip\" instead.\n"), cmdline);
if (advice_enabled(ADVICE_AM_WORK_DIR) && if (advice_enabled(ADVICE_AM_WORK_DIR) &&
is_empty_or_missing_file(am_path(state, "patch")) && is_empty_or_missing_file(am_path(state, "patch")) &&
!repo_index_has_changes(the_repository, NULL, NULL)) !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); exit(128);

View File

@ -479,7 +479,7 @@ static void print_advice(struct repository *r, int show_hint,
msg = getenv("GIT_CHERRY_PICK_HELP"); msg = getenv("GIT_CHERRY_PICK_HELP");
if (msg) { if (msg) {
advise("%s\n", msg); advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", msg);
/* /*
* A conflict has occurred but the porcelain * A conflict has occurred but the porcelain
* (typically rebase --interactive) wants to take care * (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 (show_hint) {
if (opts->no_commit) if (opts->no_commit)
advise(_("after resolving the conflicts, mark the corrected paths\n" advise_if_enabled(ADVICE_MERGE_CONFLICT,
"with 'git add <paths>' or 'git rm <paths>'")); _("after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'"));
else if (opts->action == REPLAY_PICK) else if (opts->action == REPLAY_PICK)
advise(_("After resolving the conflicts, mark them with\n" advise_if_enabled(ADVICE_MERGE_CONFLICT,
"\"git add/rm <pathspec>\", then run\n" _("After resolving the conflicts, mark them with\n"
"\"git cherry-pick --continue\".\n" "\"git add/rm <pathspec>\", then run\n"
"You can instead skip this commit with \"git cherry-pick --skip\".\n" "\"git cherry-pick --continue\".\n"
"To abort and get back to the state before \"git cherry-pick\",\n" "You can instead skip this commit with \"git cherry-pick --skip\".\n"
"run \"git cherry-pick --abort\".")); "To abort and get back to the state before \"git cherry-pick\",\n"
"run \"git cherry-pick --abort\"."));
else if (opts->action == REPLAY_REVERT) else if (opts->action == REPLAY_REVERT)
advise(_("After resolving the conflicts, mark them with\n" advise_if_enabled(ADVICE_MERGE_CONFLICT,
"\"git add/rm <pathspec>\", then run\n" _("After resolving the conflicts, mark them with\n"
"\"git revert --continue\".\n" "\"git add/rm <pathspec>\", then run\n"
"You can instead skip this commit with \"git revert --skip\".\n" "\"git revert --continue\".\n"
"To abort and get back to the state before \"git revert\",\n" "You can instead skip this commit with \"git revert --skip\".\n"
"run \"git revert --abort\".")); "To abort and get back to the state before \"git revert\",\n"
"run \"git revert --abort\"."));
else else
BUG("unexpected pick action in print_advice()"); BUG("unexpected pick action in print_advice()");
} }

View File

@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '
hint: You can instead skip this commit with "git revert --skip". hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert", hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort". hint: run "git revert --abort".
hint: Disable this message with "git config advice.mergeConflict false"
EOF EOF
test_commit --append --no-tag "double-add dream" dream dream && test_commit --append --no-tag "double-add dream" dream dream &&
test_must_fail git revert HEAD^ 2>actual && test_must_fail git revert HEAD^ 2>actual &&

View File

@ -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: 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: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort". hint: run "git cherry-pick --abort".
hint: Disable this message with "git config advice.mergeConflict false"
EOF EOF
test_must_fail git cherry-pick picked 2>actual && 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 error: could not apply \$picked... picked
hint: after resolving the conflicts, mark the corrected paths hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>' hint: with 'git add <paths>' or 'git rm <paths>'
hint: Disable this message with \"git config advice.mergeConflict false\"
EOF EOF
test_must_fail git cherry-pick --no-commit picked 2>actual && test_must_fail git cherry-pick --no-commit picked 2>actual &&

View File

@ -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' ' test_expect_success 'skip an empty patch in the middle of an am session' '
git checkout empty-commit^ && git checkout empty-commit^ &&
test_must_fail git am empty-commit.patch >err && test_must_fail git am empty-commit.patch >out 2>err &&
grep "Patch is empty." err && grep "Patch is empty." out &&
grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err && grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
git am --skip && git am --skip &&
test_path_is_missing .git/rebase-apply && 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' ' test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '
git checkout empty-commit^ && git checkout empty-commit^ &&
test_must_fail git am empty-commit.patch >err && test_must_fail git am empty-commit.patch >out 2>err &&
grep "Patch is empty." err && grep "Patch is empty." out &&
grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err && grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
git am --allow-empty >output && git am --allow-empty >output &&
grep "No changes - recorded it as an empty commit." output && grep "No changes - recorded it as an empty commit." output &&

View File

@ -59,7 +59,7 @@ test_expect_success setup '
# Also, it had the unwanted side-effect of deleting f. # Also, it had the unwanted side-effect of deleting f.
test_expect_success 'try to apply corrupted patch' ' test_expect_success 'try to apply corrupted patch' '
test_when_finished "git am --abort" && 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 && echo "error: git diff header lacks filename information (line 4)" >expected &&
test_path_is_file f && test_path_is_file f &&
test_cmp expected actual test_cmp expected actual