{"thread":{"id":"61038","subject":"[PATCH] sequencer: allow disabling conflict advice","startedAt":"2024-03-02T16:18:15Z","lastAt":"2024-03-25T16:57:58Z","messageCount":32,"participants":["Philippe Blain via GitGitGadget","Philippe Blain","Junio C Hamano","Phillip Wood","Kristoffer Haugsbakk","phillip.wood123@gmail.com","Rubén Justo"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"489776","messageId":"pull.1682.git.1709396291693.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":null,"subject":"[PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-02T16:18:11Z","receivedAt":"2024-03-02T16:18:15Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"From: Philippe Blain <levraiphilippeblain@gmail.com>\n\nAllow disabling the advice shown when a squencer operation results in a\nmerge conflict through a new config 'advice.sequencerConflict'.\n\nUpdate the tests accordingly. Note that the body of the second test in\nt3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\nescape them in the added line.\n\nSigned-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n---\n    sequencer: allow disabling conflict advice\n    \n    CC: Elijah Newren newren@gmail.com CC: Phillip Wood\n    phillip.wood@dunelm.org.uk CC: Johannes Schindelin\n    Johannes.Schindelin@gmx.de CC: ZheNing Hu adlternative@gmail.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1682%2Fphil-blain%2Fsequencer-conflict-advice-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1682/phil-blain/sequencer-conflict-advice-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1682\n\n Documentation/config/advice.txt |  3 +++\n advice.c                        |  1 +\n advice.h                        |  1 +\n sequencer.c                     | 33 ++++++++++++++++++---------------\n t/t3501-revert-cherry-pick.sh   |  1 +\n t/t3507-cherry-pick-conflict.sh |  2 ++\n 6 files changed, 26 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt\nindex c7ea70f2e2e..736b88407a4 100644\n--- a/Documentation/config/advice.txt\n+++ b/Documentation/config/advice.txt\n@@ -104,6 +104,9 @@ advice.*::\n \trmHints::\n \t\tIn case of failure in the output of linkgit:git-rm[1],\n \t\tshow directions on how to proceed from the current state.\n+\tsequencerConflict::\n+\t\tAdvice shown when a sequencer operation stops because\n+\t\tof conflicts.\n \tsequencerInUse::\n \t\tAdvice shown when a sequencer command is already in progress.\n \tskippedCherryPicks::\ndiff --git a/advice.c b/advice.c\nindex 6e9098ff089..23e48194e74 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -71,6 +71,7 @@ static struct {\n \t[ADVICE_RESET_NO_REFRESH_WARNING]\t\t= { \"resetNoRefresh\" },\n \t[ADVICE_RESOLVE_CONFLICT]\t\t\t= { \"resolveConflict\" },\n \t[ADVICE_RM_HINTS]\t\t\t\t= { \"rmHints\" },\n+\t[ADVICE_SEQUENCER_CONFLICT]                     = { \"sequencerConflict\" },\n \t[ADVICE_SEQUENCER_IN_USE]\t\t\t= { \"sequencerInUse\" },\n \t[ADVICE_SET_UPSTREAM_FAILURE]\t\t\t= { \"setUpstreamFailure\" },\n \t[ADVICE_SKIPPED_CHERRY_PICKS]\t\t\t= { \"skippedCherryPicks\" },\ndiff --git a/advice.h b/advice.h\nindex 9d4f49ae38b..98966f8991d 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -40,6 +40,7 @@ enum advice_type {\n \tADVICE_RESOLVE_CONFLICT,\n \tADVICE_RM_HINTS,\n \tADVICE_SEQUENCER_IN_USE,\n+\tADVICE_SEQUENCER_CONFLICT,\n \tADVICE_SET_UPSTREAM_FAILURE,\n \tADVICE_SKIPPED_CHERRY_PICKS,\n \tADVICE_STATUS_AHEAD_BEHIND_WARNING,\ndiff --git a/sequencer.c b/sequencer.c\nindex f49a871ac06..3e2f028ce2d 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -467,7 +467,7 @@ static void print_advice(struct repository *r, int show_hint,\n \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n \n \tif (msg) {\n-\t\tadvise(\"%s\\n\", msg);\n+\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n \t\t/*\n \t\t * A conflict has occurred but the porcelain\n \t\t * (typically rebase --interactive) wants to take care\n@@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n \n \tif (show_hint) {\n \t\tif (opts->no_commit)\n-\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n-\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n+\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n+\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n \t\telse if (opts->action == REPLAY_PICK)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n-\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n \t\telse if (opts->action == REPLAY_REVERT)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n-\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n \t\telse\n \t\t\tBUG(\"unexpected pick action in print_advice()\");\n \t}\ndiff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\nindex aeab689a98d..bc7c878b236 100755\n--- a/t/t3501-revert-cherry-pick.sh\n+++ b/t/t3501-revert-cherry-pick.sh\n@@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '\n \thint: You can instead skip this commit with \"git revert --skip\".\n \thint: To abort and get back to the state before \"git revert\",\n \thint: run \"git revert --abort\".\n+\thint: Disable this message with \"git config advice.sequencerConflict false\"\n \tEOF\n \ttest_commit --append --no-tag \"double-add dream\" dream dream &&\n \ttest_must_fail git revert HEAD^ 2>actual &&\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex c88d597b126..a643893dcbd 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' '\n \thint: You can instead skip this commit with \"git cherry-pick --skip\".\n \thint: To abort and get back to the state before \"git cherry-pick\",\n \thint: run \"git cherry-pick --abort\".\n+\thint: Disable this message with \"git config advice.sequencerConflict false\"\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n@@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' \"\n \terror: could not apply \\$picked... picked\n \thint: after resolving the conflicts, mark the corrected paths\n \thint: with 'git add <paths>' or 'git rm <paths>'\n+\thint: Disable this message with \\\"git config advice.sequencerConflict false\\\"\n \tEOF\n \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n \n\nbase-commit: 0f9d4d28b7e6021b7e6db192b7bf47bd3a0d0d1d\n-- \ngitgitgadget\n"},{"id":"489779","messageId":"16c57c5f-6296-041e-d747-881c5c670834@gmail.com","threadId":"61038","inReplyTo":"pull.1682.git.1709396291693.gitgitgadget@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-02T16:32:23Z","receivedAt":"2024-03-02T16:32:25Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi, \n\nLe 2024-03-02 à 11:18, Philippe Blain via GitGitGadget a écrit :\n> From: Philippe Blain <levraiphilippeblain@gmail.com>\n> \n> Allow disabling the advice shown when a squencer operation results in a\n> merge conflict through a new config 'advice.sequencerConflict'.\n> \n> Update the tests accordingly. Note that the body of the second test in\n> t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\n> escape them in the added line.\n> \n> Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n\nI meant to CC your addresses in https://lore.kernel.org/git/pull.1682.git.1709396291693.gitgitgadget@gmail.com/\nwhich I'm responding to, but the CC's did not get through somehow.\n\nCheers,\n\nPhilippe.\n"},{"id":"489827","messageId":"xmqqwmqiudna.fsf@gitster.g","threadId":"61038","inReplyTo":"pull.1682.git.1709396291693.gitgitgadget@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-03T22:57:45Z","receivedAt":"2024-03-03T22:57:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Philippe Blain via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n>  \tif (msg) {\n> -\t\tadvise(\"%s\\n\", msg);\n> +\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n>  \t\t/*\n>  \t\t * A conflict has occurred but the porcelain\n>  \t\t * (typically rebase --interactive) wants to take care\n\nThis hunk is good.  The block removes the CHERRY_PICK_HEAD after\ngiving this advice and then returns.\n\n> @@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n>  \n>  \tif (show_hint) {\n>  \t\tif (opts->no_commit)\n> -\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n> -\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n> +\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n>  \t\telse if (opts->action == REPLAY_PICK)\n> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> -\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n> -\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n> -\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n> -\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> +\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n> +\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n>  \t\telse if (opts->action == REPLAY_REVERT)\n> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> -\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n> -\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n> -\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n> -\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> +\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n> +\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n>  \t\telse\n>  \t\t\tBUG(\"unexpected pick action in print_advice()\");\n>  \t}\n\nThis hunk can be improved.  If I were doing this patch, I probably\nwould have just done\n\n-\tif (show_hint) {\n+\tif (show_hint && advice_enabled(ADVICE_SEQUENCER_CONFLICT)) {\n\nand nothing else, and doing so would keep the block easier to extend\nand maintain in the future.\n\nBecause the block is all about \"show_hint\", we have code to print\nadvice messages and nothing else in it currently, and more\nimportantly, we will not add anything other than code to print\nadvice messages in it.  Because of that, skipping everything when\nADVICE_SEQUENCER_CONFLICT is not enabled will not cause problems\n(unlike the earlier hunk---which will break if we added \"&&\nadvice_enabled()\" to \"if (msg)\").  That way, when somebody teaches\nthis code a new kind of opts->action, they do not have to say\n\"advice_if_enabled(ADVICE_SEQUENCER_CONFLICT()\"; they can just use\n\"advise()\".\n\n> diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\n> index aeab689a98d..bc7c878b236 100755\n> --- a/t/t3501-revert-cherry-pick.sh\n> +++ b/t/t3501-revert-cherry-pick.sh\n\nAll changes to the file look good.\n"},{"id":"489866","messageId":"3df4790a-7ee1-4c72-a3da-ba8a48d546b8@gmail.com","threadId":"61038","inReplyTo":"pull.1682.git.1709396291693.gitgitgadget@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-04T10:12:33Z","receivedAt":"2024-03-04T10:12:36Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Philippe\n\nOn 02/03/2024 16:18, Philippe Blain via GitGitGadget wrote:\n> From: Philippe Blain <levraiphilippeblain@gmail.com>\n> \n> Allow disabling the advice shown when a squencer operation results in a\n> merge conflict through a new config 'advice.sequencerConflict'.\n\nWe already have \"advice.resolveConflict\" to suppress conflict advice. \nCan we extend that to these conflict messages rather than introducing a \nnew category? As far as the user is concerned they are all messages \nabout resolving conflicts - I don't really see why they'd want to \nsuppress the messages from \"git merge\" separately to \"git rebase\" (and \nif they do then why is it ok to suppress the messages from \"git merge\", \n\"git rebase\" and \"git cherry-pick\" with a single setting). It would also \nbe good to update the \"rebase --apply\" implementation to respect this \nadvice config to be consistent with \"rebase --merge\".\n\nBest Wishes\n\nPhillip\n\n> Update the tests accordingly. Note that the body of the second test in\n> t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\n> escape them in the added line.\n> \n> Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n> ---\n>      sequencer: allow disabling conflict advice\n>      \n>      CC: Elijah Newren newren@gmail.com CC: Phillip Wood\n>      phillip.wood@dunelm.org.uk CC: Johannes Schindelin\n>      Johannes.Schindelin@gmx.de CC: ZheNing Hu adlternative@gmail.com\n> \n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1682%2Fphil-blain%2Fsequencer-conflict-advice-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1682/phil-blain/sequencer-conflict-advice-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1682\n> \n>   Documentation/config/advice.txt |  3 +++\n>   advice.c                        |  1 +\n>   advice.h                        |  1 +\n>   sequencer.c                     | 33 ++++++++++++++++++---------------\n>   t/t3501-revert-cherry-pick.sh   |  1 +\n>   t/t3507-cherry-pick-conflict.sh |  2 ++\n>   6 files changed, 26 insertions(+), 15 deletions(-)\n> \n> diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt\n> index c7ea70f2e2e..736b88407a4 100644\n> --- a/Documentation/config/advice.txt\n> +++ b/Documentation/config/advice.txt\n> @@ -104,6 +104,9 @@ advice.*::\n>   \trmHints::\n>   \t\tIn case of failure in the output of linkgit:git-rm[1],\n>   \t\tshow directions on how to proceed from the current state.\n> +\tsequencerConflict::\n> +\t\tAdvice shown when a sequencer operation stops because\n> +\t\tof conflicts.\n>   \tsequencerInUse::\n>   \t\tAdvice shown when a sequencer command is already in progress.\n>   \tskippedCherryPicks::\n> diff --git a/advice.c b/advice.c\n> index 6e9098ff089..23e48194e74 100644\n> --- a/advice.c\n> +++ b/advice.c\n> @@ -71,6 +71,7 @@ static struct {\n>   \t[ADVICE_RESET_NO_REFRESH_WARNING]\t\t= { \"resetNoRefresh\" },\n>   \t[ADVICE_RESOLVE_CONFLICT]\t\t\t= { \"resolveConflict\" },\n>   \t[ADVICE_RM_HINTS]\t\t\t\t= { \"rmHints\" },\n> +\t[ADVICE_SEQUENCER_CONFLICT]                     = { \"sequencerConflict\" },\n>   \t[ADVICE_SEQUENCER_IN_USE]\t\t\t= { \"sequencerInUse\" },\n>   \t[ADVICE_SET_UPSTREAM_FAILURE]\t\t\t= { \"setUpstreamFailure\" },\n>   \t[ADVICE_SKIPPED_CHERRY_PICKS]\t\t\t= { \"skippedCherryPicks\" },\n> diff --git a/advice.h b/advice.h\n> index 9d4f49ae38b..98966f8991d 100644\n> --- a/advice.h\n> +++ b/advice.h\n> @@ -40,6 +40,7 @@ enum advice_type {\n>   \tADVICE_RESOLVE_CONFLICT,\n>   \tADVICE_RM_HINTS,\n>   \tADVICE_SEQUENCER_IN_USE,\n> +\tADVICE_SEQUENCER_CONFLICT,\n>   \tADVICE_SET_UPSTREAM_FAILURE,\n>   \tADVICE_SKIPPED_CHERRY_PICKS,\n>   \tADVICE_STATUS_AHEAD_BEHIND_WARNING,\n> diff --git a/sequencer.c b/sequencer.c\n> index f49a871ac06..3e2f028ce2d 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -467,7 +467,7 @@ static void print_advice(struct repository *r, int show_hint,\n>   \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n>   \n>   \tif (msg) {\n> -\t\tadvise(\"%s\\n\", msg);\n> +\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n>   \t\t/*\n>   \t\t * A conflict has occurred but the porcelain\n>   \t\t * (typically rebase --interactive) wants to take care\n> @@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n>   \n>   \tif (show_hint) {\n>   \t\tif (opts->no_commit)\n> -\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n> -\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n> +\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n>   \t\telse if (opts->action == REPLAY_PICK)\n> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> -\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n> -\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n> -\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n> -\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> +\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n> +\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n>   \t\telse if (opts->action == REPLAY_REVERT)\n> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> -\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n> -\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n> -\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n> -\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n> +\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n> +\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n>   \t\telse\n>   \t\t\tBUG(\"unexpected pick action in print_advice()\");\n>   \t}\n> diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\n> index aeab689a98d..bc7c878b236 100755\n> --- a/t/t3501-revert-cherry-pick.sh\n> +++ b/t/t3501-revert-cherry-pick.sh\n> @@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '\n>   \thint: You can instead skip this commit with \"git revert --skip\".\n>   \thint: To abort and get back to the state before \"git revert\",\n>   \thint: run \"git revert --abort\".\n> +\thint: Disable this message with \"git config advice.sequencerConflict false\"\n>   \tEOF\n>   \ttest_commit --append --no-tag \"double-add dream\" dream dream &&\n>   \ttest_must_fail git revert HEAD^ 2>actual &&\n> diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\n> index c88d597b126..a643893dcbd 100755\n> --- a/t/t3507-cherry-pick-conflict.sh\n> +++ b/t/t3507-cherry-pick-conflict.sh\n> @@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' '\n>   \thint: You can instead skip this commit with \"git cherry-pick --skip\".\n>   \thint: To abort and get back to the state before \"git cherry-pick\",\n>   \thint: run \"git cherry-pick --abort\".\n> +\thint: Disable this message with \"git config advice.sequencerConflict false\"\n>   \tEOF\n>   \ttest_must_fail git cherry-pick picked 2>actual &&\n>   \n> @@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' \"\n>   \terror: could not apply \\$picked... picked\n>   \thint: after resolving the conflicts, mark the corrected paths\n>   \thint: with 'git add <paths>' or 'git rm <paths>'\n> +\thint: Disable this message with \\\"git config advice.sequencerConflict false\\\"\n>   \tEOF\n>   \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n>   \n> \n> base-commit: 0f9d4d28b7e6021b7e6db192b7bf47bd3a0d0d1d\n"},{"id":"489867","messageId":"6a31efcc-c6c2-4729-80b9-eecff4ec9e31@gmail.com","threadId":"61038","inReplyTo":"3df4790a-7ee1-4c72-a3da-ba8a48d546b8@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-04T10:27:30Z","receivedAt":"2024-03-04T10:27:33Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"> We already have \"advice.resolveConflict\" to suppress conflict advice. \n\nOh looking more closely that is doing something slightly different - it \nsuppresses advice about pre-existing conflicts in the index when \nstarting a merge etc. So we probably do need a new config variable but I \nthink it should have a generic name - not be sequencer specific so we \ncan extend its scope in the future to \"git merge\", \"git am -3\", \"git \nstash\" etc.\n\nBest Wishes\n\nPhillip\n"},{"id":"489907","messageId":"xmqqy1axq3t1.fsf@gitster.g","threadId":"61038","inReplyTo":"6a31efcc-c6c2-4729-80b9-eecff4ec9e31@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-04T17:56:10Z","receivedAt":"2024-03-04T17:56:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> ... So we probably do need a new config variable but\n> I think it should have a generic name - not be sequencer specific so\n> we can extend its scope in the future to \"git merge\", \"git am -3\",\n> \"git stash\" etc.\n\nA very good point.  Thanks for your careful thinking.\n"},{"id":"490297","messageId":"6ef490d2-ce0a-f8bd-8079-6b4ef3e37eda@gmail.com","threadId":"61038","inReplyTo":"xmqqwmqiudna.fsf@gitster.g","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-09T17:22:23Z","receivedAt":"2024-03-09T17:22:24Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Junio,\n\nLe 2024-03-03 à 17:57, Junio C Hamano a écrit :\n> \"Philippe Blain via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>>  \tif (msg) {\n>> -\t\tadvise(\"%s\\n\", msg);\n>> +\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n>>  \t\t/*\n>>  \t\t * A conflict has occurred but the porcelain\n>>  \t\t * (typically rebase --interactive) wants to take care\n> \n> This hunk is good.  The block removes the CHERRY_PICK_HEAD after\n> giving this advice and then returns.\n> \n>> @@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n>>  \n>>  \tif (show_hint) {\n>>  \t\tif (opts->no_commit)\n>> -\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n>> -\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>> +\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n>> +\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n>>  \t\telse if (opts->action == REPLAY_PICK)\n>> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n>> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>> -\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n>> -\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n>> -\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n>> -\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n>> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>> +\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n>> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n>> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n>> +\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n>>  \t\telse if (opts->action == REPLAY_REVERT)\n>> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n>> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>> -\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n>> -\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n>> -\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n>> -\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n>> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>> +\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n>> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n>> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n>> +\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n>>  \t\telse\n>>  \t\t\tBUG(\"unexpected pick action in print_advice()\");\n>>  \t}\n> \n> This hunk can be improved.  If I were doing this patch, I probably\n> would have just done\n> \n> -\tif (show_hint) {\n> +\tif (show_hint && advice_enabled(ADVICE_SEQUENCER_CONFLICT)) {\n> \n> and nothing else, and doing so would keep the block easier to extend\n> and maintain in the future.\n> \n> Because the block is all about \"show_hint\", we have code to print\n> advice messages and nothing else in it currently, and more\n> importantly, we will not add anything other than code to print\n> advice messages in it.  Because of that, skipping everything when\n> ADVICE_SEQUENCER_CONFLICT is not enabled will not cause problems\n> (unlike the earlier hunk---which will break if we added \"&&\n> advice_enabled()\" to \"if (msg)\").  That way, when somebody teaches\n> this code a new kind of opts->action, they do not have to say\n> \"advice_if_enabled(ADVICE_SEQUENCER_CONFLICT()\"; they can just use\n> \"advise()\".\n\nThat's true and makes the changes simpler, thank you for the suggestion.\nI'll do that in v2.\n\nPhilippe.\n"},{"id":"490300","messageId":"12c84208-23a7-5ba7-18a9-822d9a8f66fa@gmail.com","threadId":"61038","inReplyTo":"xmqqy1axq3t1.fsf@gitster.g","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-09T17:53:38Z","receivedAt":"2024-03-09T17:53:40Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Phillip and Junio,\n\nLe 2024-03-04 à 12:56, Junio C Hamano a écrit :\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> \n>> ... So we probably do need a new config variable but\n>> I think it should have a generic name - not be sequencer specific so\n>> we can extend its scope in the future to \"git merge\", \"git am -3\",\n>> \"git stash\" etc.\n> \n> A very good point.  Thanks for your careful thinking.\n\nOK, I agree we can make the new advice more generic, but I'm lacking\ninspiration for the name. Maybe 'advice.mergeConflicted' ? \nOr 'advice.resolveConflictedMerge' ? though this is close to the existing \n'resolveConflict'... \nMaybe just 'advice.mergeConflict' ?\n\nThanks, \nPhilippe.\n"},{"id":"490303","messageId":"d83c271b-04c1-f3fc-d922-76f73ac2031a@gmail.com","threadId":"61038","inReplyTo":"3df4790a-7ee1-4c72-a3da-ba8a48d546b8@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-09T18:01:00Z","receivedAt":"2024-03-09T18:01:02Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Phillip,\n\nLe 2024-03-04 à 05:12, Phillip Wood a écrit :\n> Hi Philippe\n> \n> On 02/03/2024 16:18, Philippe Blain via GitGitGadget wrote:\n> \n> It would also be good to update the \"rebase --apply\" implementation to respect this advice config to be consistent with \"rebase --merge\".\nYes, this is a good idea. This would take care of 'git am' at the same time\nsince both are implemented in builtin/am.c::die_user_resolve.\n\nThanks,\nPhilippe.\n"},{"id":"490306","messageId":"570a8736-5552-6279-4aea-8acdf8af50df@gmail.com","threadId":"61038","inReplyTo":"6ef490d2-ce0a-f8bd-8079-6b4ef3e37eda@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-09T18:58:45Z","receivedAt":"2024-03-09T18:58:48Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Le 2024-03-09 à 12:22, Philippe Blain a écrit :\n> Hi Junio,\n> \n> Le 2024-03-03 à 17:57, Junio C Hamano a écrit :\n>> \"Philippe Blain via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>>\n>>>  \tif (msg) {\n>>> -\t\tadvise(\"%s\\n\", msg);\n>>> +\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n>>>  \t\t/*\n>>>  \t\t * A conflict has occurred but the porcelain\n>>>  \t\t * (typically rebase --interactive) wants to take care\n>>\n>> This hunk is good.  The block removes the CHERRY_PICK_HEAD after\n>> giving this advice and then returns.\n>>\n>>> @@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n>>>  \n>>>  \tif (show_hint) {\n>>>  \t\tif (opts->no_commit)\n>>> -\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n>>> -\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n>>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>>> +\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n>>> +\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n>>>  \t\telse if (opts->action == REPLAY_PICK)\n>>> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n>>> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>>> -\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n>>> -\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n>>> -\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n>>> -\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n>>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>>> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n>>> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>>> +\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n>>> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n>>> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n>>> +\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n>>>  \t\telse if (opts->action == REPLAY_REVERT)\n>>> -\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n>>> -\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>>> -\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n>>> -\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n>>> -\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n>>> -\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n>>> +\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n>>> +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n>>> +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n>>> +\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n>>> +\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n>>> +\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n>>> +\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n>>>  \t\telse\n>>>  \t\t\tBUG(\"unexpected pick action in print_advice()\");\n>>>  \t}\n>>\n>> This hunk can be improved.  If I were doing this patch, I probably\n>> would have just done\n>>\n>> -\tif (show_hint) {\n>> +\tif (show_hint && advice_enabled(ADVICE_SEQUENCER_CONFLICT)) {\n>>\n>> and nothing else, and doing so would keep the block easier to extend\n>> and maintain in the future.\n>>\n>> Because the block is all about \"show_hint\", we have code to print\n>> advice messages and nothing else in it currently, and more\n>> importantly, we will not add anything other than code to print\n>> advice messages in it.  Because of that, skipping everything when\n>> ADVICE_SEQUENCER_CONFLICT is not enabled will not cause problems\n>> (unlike the earlier hunk---which will break if we added \"&&\n>> advice_enabled()\" to \"if (msg)\").  That way, when somebody teaches\n>> this code a new kind of opts->action, they do not have to say\n>> \"advice_if_enabled(ADVICE_SEQUENCER_CONFLICT()\"; they can just use\n>> \"advise()\".\n> \n> That's true and makes the changes simpler, thank you for the suggestion.\n> I'll do that in v2.\n\nThinking about this more and looking at the code, using 'advice_enabled' in the condition\ninstead of using 'advise_if_enabled' for each message has a side effect:\nthe text \"hint: Disable this message with \"git config advice.sequencerConflict false\"\nwill not appear, which I find less user friendly...\n\nPhilippe.\n"},{"id":"490307","messageId":"b52a8678-a13f-455b-a817-2df2b4fab795@gmail.com","threadId":"61038","inReplyTo":"12c84208-23a7-5ba7-18a9-822d9a8f66fa@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-09T19:15:16Z","receivedAt":"2024-03-09T19:15:19Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Philippe\n\nOn 09/03/2024 17:53, Philippe Blain wrote:\n> Le 2024-03-04 à 12:56, Junio C Hamano a écrit :\n>> Phillip Wood <phillip.wood123@gmail.com> writes:\n>>\n>>> ... So we probably do need a new config variable but\n>>> I think it should have a generic name - not be sequencer specific so\n>>> we can extend its scope in the future to \"git merge\", \"git am -3\",\n>>> \"git stash\" etc.\n>>\n>> A very good point.  Thanks for your careful thinking.\n> \n> OK, I agree we can make the new advice more generic, but I'm lacking\n> inspiration for the name. Maybe 'advice.mergeConflicted' ?\n> Or 'advice.resolveConflictedMerge' ? though this is close to the existing\n> 'resolveConflict'...\n> Maybe just 'advice.mergeConflict' ?\n\n'advice.mergeConflict' sounds good to me\n\nBest Wishes\n\nPhillip\n\n"},{"id":"490308","messageId":"xmqqle6rch89.fsf@gitster.g","threadId":"61038","inReplyTo":"570a8736-5552-6279-4aea-8acdf8af50df@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-09T19:55:50Z","receivedAt":"2024-03-09T19:55:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Philippe Blain <levraiphilippeblain@gmail.com> writes:\n\n> Thinking about this more and looking at the code, using 'advice_enabled' in the condition\n> instead of using 'advise_if_enabled' for each message has a side effect:\n> the text \"hint: Disable this message with \"git config advice.sequencerConflict false\"\n> will not appear, which I find less user friendly...\n\nGood eyes.\n\nI agree that you have to do that part yourself at the end of that\n\"if () { ... }\" block using turn_off_instructions[] string.\n"},{"id":"490309","messageId":"xmqqh6hfch7j.fsf@gitster.g","threadId":"61038","inReplyTo":"b52a8678-a13f-455b-a817-2df2b4fab795@gmail.com","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-09T19:56:16Z","receivedAt":"2024-03-09T19:56:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n>> Maybe just 'advice.mergeConflict' ?\n>\n> 'advice.mergeConflict' sounds good to me\n\nYup, looks good to me, too.\n\n\n"},{"id":"490313","messageId":"xmqqh6hf0z8v.fsf@gitster.g","threadId":"61038","inReplyTo":"xmqqle6rch89.fsf@gitster.g","subject":"Re: [PATCH] sequencer: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-09T23:19:44Z","receivedAt":"2024-03-09T23:19:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Philippe Blain <levraiphilippeblain@gmail.com> writes:\n>\n>> Thinking about this more and looking at the code, using 'advice_enabled' in the condition\n>> instead of using 'advise_if_enabled' for each message has a side effect:\n>> the text \"hint: Disable this message with \"git config advice.sequencerConflict false\"\n>> will not appear, which I find less user friendly...\n>\n> Good eyes.\n>\n> I agree that you have to do that part yourself at the end of that\n> \"if () { ... }\" block using turn_off_instructions[] string.\n\nForgot to add \"... which is an unnecessary chore\" at the end.\n\nThanks.\n"},{"id":"490345","messageId":"pull.1682.v2.git.1710100261.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.git.1709396291693.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] Allow disabling advice shown after merge conflicts","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-10T19:50:59Z","receivedAt":"2024-03-10T19:51:05Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"This series introduces a new config 'advice.mergeConflict' and uses it to\nallow disabling the advice shown when 'git rebase', 'git cherry-pick', 'git\nrevert', 'git rebase --apply' and 'git am' stop because of conflicts.\n\nChanges since v1:\n\n * renamed the new advice to 'advice.mergeConflict' to make it non-sequencer\n   specific\n * added 2/2 which uses the advice in builtin/am, which covers 'git rebase\n   --apply' and 'git am'\n\nNote that the code path where 'git rebase --apply' stops because of\nconflicts is not covered by the tests but I tested it manually using this\ndiff:\n\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 47534f1062..34eac2e6f4 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -374,7 +374,7 @@ test_pull_autostash_fail ()\n     echo conflicting >>seq.txt &&\n     test_tick &&\n     git commit -m \"Create conflict\" seq.txt &&\n-\ttest_must_fail git pull --rebase . seq 2>err >out &&\n+\ttest_must_fail git -c rebase.backend=apply pull --rebase . seq 2>err >out &&\n     test_grep \"Resolve all conflicts manually\" err\n '\n\n\nPhilippe Blain (2):\n  sequencer: allow disabling conflict advice\n  builtin/am: allow disabling conflict advice\n\n Documentation/config/advice.txt |  2 ++\n advice.c                        |  1 +\n advice.h                        |  1 +\n builtin/am.c                    | 14 +++++++++-----\n sequencer.c                     | 33 ++++++++++++++++++---------------\n t/t3501-revert-cherry-pick.sh   |  1 +\n t/t3507-cherry-pick-conflict.sh |  2 ++\n t/t4150-am.sh                   |  8 ++++----\n t/t4254-am-corrupt.sh           |  2 +-\n 9 files changed, 39 insertions(+), 25 deletions(-)\n\n\nbase-commit: 0f9d4d28b7e6021b7e6db192b7bf47bd3a0d0d1d\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1682%2Fphil-blain%2Fsequencer-conflict-advice-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1682/phil-blain/sequencer-conflict-advice-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/1682\n\nRange-diff vs v1:\n\n 1:  e929d3381cf ! 1:  a2ce6fd24c2 sequencer: allow disabling conflict advice\n     @@ Commit message\n          sequencer: allow disabling conflict advice\n      \n          Allow disabling the advice shown when a squencer operation results in a\n     -    merge conflict through a new config 'advice.sequencerConflict'.\n     +    merge conflict through a new config 'advice.mergeConflict', which is\n     +    named generically such that it can be used by other commands eventually.\n     +\n     +    Note that we use 'advise_if_enabled' for each message in the second hunk\n     +    in sequencer.c, instead of using 'if (show_hints &&\n     +    advice_enabled(...)', because the former instructs the user how to\n     +    disable the advice, which is more user-friendly.\n      \n          Update the tests accordingly. Note that the body of the second test in\n          t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\n     @@ Commit message\n      \n       ## Documentation/config/advice.txt ##\n      @@ Documentation/config/advice.txt: advice.*::\n     - \trmHints::\n     - \t\tIn case of failure in the output of linkgit:git-rm[1],\n     - \t\tshow directions on how to proceed from the current state.\n     -+\tsequencerConflict::\n     -+\t\tAdvice shown when a sequencer operation stops because\n     -+\t\tof conflicts.\n     - \tsequencerInUse::\n     - \t\tAdvice shown when a sequencer command is already in progress.\n     - \tskippedCherryPicks::\n     + \t\tAdvice on how to set your identity configuration when\n     + \t\tyour information is guessed from the system username and\n     + \t\tdomain name.\n     ++\tmergeConflict::\n     ++\t\tAdvice shown when various commands stop because of conflicts.\n     + \tnestedTag::\n     + \t\tAdvice shown if a user attempts to recursively tag a tag object.\n     + \tpushAlreadyExists::\n      \n       ## advice.c ##\n      @@ advice.c: static struct {\n     - \t[ADVICE_RESET_NO_REFRESH_WARNING]\t\t= { \"resetNoRefresh\" },\n     - \t[ADVICE_RESOLVE_CONFLICT]\t\t\t= { \"resolveConflict\" },\n     - \t[ADVICE_RM_HINTS]\t\t\t\t= { \"rmHints\" },\n     -+\t[ADVICE_SEQUENCER_CONFLICT]                     = { \"sequencerConflict\" },\n     - \t[ADVICE_SEQUENCER_IN_USE]\t\t\t= { \"sequencerInUse\" },\n     - \t[ADVICE_SET_UPSTREAM_FAILURE]\t\t\t= { \"setUpstreamFailure\" },\n     - \t[ADVICE_SKIPPED_CHERRY_PICKS]\t\t\t= { \"skippedCherryPicks\" },\n     + \t[ADVICE_GRAFT_FILE_DEPRECATED]\t\t\t= { \"graftFileDeprecated\" },\n     + \t[ADVICE_IGNORED_HOOK]\t\t\t\t= { \"ignoredHook\" },\n     + \t[ADVICE_IMPLICIT_IDENTITY]\t\t\t= { \"implicitIdentity\" },\n     ++\t[ADVICE_MERGE_CONFLICT]\t\t\t\t= { \"mergeConflict\" },\n     + \t[ADVICE_NESTED_TAG]\t\t\t\t= { \"nestedTag\" },\n     + \t[ADVICE_OBJECT_NAME_WARNING]\t\t\t= { \"objectNameWarning\" },\n     + \t[ADVICE_PUSH_ALREADY_EXISTS]\t\t\t= { \"pushAlreadyExists\" },\n      \n       ## advice.h ##\n      @@ advice.h: enum advice_type {\n     - \tADVICE_RESOLVE_CONFLICT,\n     - \tADVICE_RM_HINTS,\n     - \tADVICE_SEQUENCER_IN_USE,\n     -+\tADVICE_SEQUENCER_CONFLICT,\n     - \tADVICE_SET_UPSTREAM_FAILURE,\n     - \tADVICE_SKIPPED_CHERRY_PICKS,\n     - \tADVICE_STATUS_AHEAD_BEHIND_WARNING,\n     + \tADVICE_IGNORED_HOOK,\n     + \tADVICE_IMPLICIT_IDENTITY,\n     + \tADVICE_NESTED_TAG,\n     ++\tADVICE_MERGE_CONFLICT,\n     + \tADVICE_OBJECT_NAME_WARNING,\n     + \tADVICE_PUSH_ALREADY_EXISTS,\n     + \tADVICE_PUSH_FETCH_FIRST,\n      \n       ## sequencer.c ##\n      @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n       \n       \tif (msg) {\n      -\t\tadvise(\"%s\\n\", msg);\n     -+\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT, \"%s\\n\", msg);\n     ++\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\\n\", msg);\n       \t\t/*\n       \t\t * A conflict has occurred but the porcelain\n       \t\t * (typically rebase --interactive) wants to take care\n     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n       \t\tif (opts->no_commit)\n      -\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n      -\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n     -+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n     ++\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n      +\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n      +\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n       \t\telse if (opts->action == REPLAY_PICK)\n     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n      -\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n      -\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n      -\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n     -+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n     ++\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n      +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n      +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n      +\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n      -\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n      -\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n      -\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n     -+\t\t\tadvise_if_enabled(ADVICE_SEQUENCER_CONFLICT,\n     ++\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n      +\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n      +\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n      +\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n     @@ t/t3501-revert-cherry-pick.sh: test_expect_success 'advice from failed revert' '\n       \thint: You can instead skip this commit with \"git revert --skip\".\n       \thint: To abort and get back to the state before \"git revert\",\n       \thint: run \"git revert --abort\".\n     -+\thint: Disable this message with \"git config advice.sequencerConflict false\"\n     ++\thint: Disable this message with \"git config advice.mergeConflict false\"\n       \tEOF\n       \ttest_commit --append --no-tag \"double-add dream\" dream dream &&\n       \ttest_must_fail git revert HEAD^ 2>actual &&\n     @@ t/t3507-cherry-pick-conflict.sh: test_expect_success 'advice from failed cherry-\n       \thint: You can instead skip this commit with \"git cherry-pick --skip\".\n       \thint: To abort and get back to the state before \"git cherry-pick\",\n       \thint: run \"git cherry-pick --abort\".\n     -+\thint: Disable this message with \"git config advice.sequencerConflict false\"\n     ++\thint: Disable this message with \"git config advice.mergeConflict false\"\n       \tEOF\n       \ttest_must_fail git cherry-pick picked 2>actual &&\n       \n     @@ t/t3507-cherry-pick-conflict.sh: test_expect_success 'advice from failed cherry-\n       \terror: could not apply \\$picked... picked\n       \thint: after resolving the conflicts, mark the corrected paths\n       \thint: with 'git add <paths>' or 'git rm <paths>'\n     -+\thint: Disable this message with \\\"git config advice.sequencerConflict false\\\"\n     ++\thint: Disable this message with \\\"git config advice.mergeConflict false\\\"\n       \tEOF\n       \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n       \n -:  ----------- > 2:  3235542cc6f builtin/am: allow disabling conflict advice\n\n-- \ngitgitgadget\n"},{"id":"490346","messageId":"a2ce6fd24c270fcc89439cd7d119c701dd262ec5.1710100261.git.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v2.git.1710100261.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] sequencer: allow disabling conflict advice","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-10T19:51:00Z","receivedAt":"2024-03-10T19:51:05Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"From: Philippe Blain <levraiphilippeblain@gmail.com>\n\nAllow disabling the advice shown when a squencer operation results in a\nmerge conflict through a new config 'advice.mergeConflict', which is\nnamed generically such that it can be used by other commands eventually.\n\nNote that we use 'advise_if_enabled' for each message in the second hunk\nin sequencer.c, instead of using 'if (show_hints &&\nadvice_enabled(...)', because the former instructs the user how to\ndisable the advice, which is more user-friendly.\n\nUpdate the tests accordingly. Note that the body of the second test in\nt3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\nescape them in the added line.\n\nSigned-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n---\n Documentation/config/advice.txt |  2 ++\n advice.c                        |  1 +\n advice.h                        |  1 +\n sequencer.c                     | 33 ++++++++++++++++++---------------\n t/t3501-revert-cherry-pick.sh   |  1 +\n t/t3507-cherry-pick-conflict.sh |  2 ++\n 6 files changed, 25 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt\nindex c7ea70f2e2e..a1178284b23 100644\n--- a/Documentation/config/advice.txt\n+++ b/Documentation/config/advice.txt\n@@ -56,6 +56,8 @@ advice.*::\n \t\tAdvice on how to set your identity configuration when\n \t\tyour information is guessed from the system username and\n \t\tdomain name.\n+\tmergeConflict::\n+\t\tAdvice shown when various commands stop because of conflicts.\n \tnestedTag::\n \t\tAdvice shown if a user attempts to recursively tag a tag object.\n \tpushAlreadyExists::\ndiff --git a/advice.c b/advice.c\nindex 6e9098ff089..ecce0f5a803 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -57,6 +57,7 @@ static struct {\n \t[ADVICE_GRAFT_FILE_DEPRECATED]\t\t\t= { \"graftFileDeprecated\" },\n \t[ADVICE_IGNORED_HOOK]\t\t\t\t= { \"ignoredHook\" },\n \t[ADVICE_IMPLICIT_IDENTITY]\t\t\t= { \"implicitIdentity\" },\n+\t[ADVICE_MERGE_CONFLICT]\t\t\t\t= { \"mergeConflict\" },\n \t[ADVICE_NESTED_TAG]\t\t\t\t= { \"nestedTag\" },\n \t[ADVICE_OBJECT_NAME_WARNING]\t\t\t= { \"objectNameWarning\" },\n \t[ADVICE_PUSH_ALREADY_EXISTS]\t\t\t= { \"pushAlreadyExists\" },\ndiff --git a/advice.h b/advice.h\nindex 9d4f49ae38b..89117cdeb77 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -26,6 +26,7 @@ enum advice_type {\n \tADVICE_IGNORED_HOOK,\n \tADVICE_IMPLICIT_IDENTITY,\n \tADVICE_NESTED_TAG,\n+\tADVICE_MERGE_CONFLICT,\n \tADVICE_OBJECT_NAME_WARNING,\n \tADVICE_PUSH_ALREADY_EXISTS,\n \tADVICE_PUSH_FETCH_FIRST,\ndiff --git a/sequencer.c b/sequencer.c\nindex f49a871ac06..d61bbe37c8c 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -467,7 +467,7 @@ static void print_advice(struct repository *r, int show_hint,\n \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n \n \tif (msg) {\n-\t\tadvise(\"%s\\n\", msg);\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\\n\", msg);\n \t\t/*\n \t\t * A conflict has occurred but the porcelain\n \t\t * (typically rebase --interactive) wants to take care\n@@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n \n \tif (show_hint) {\n \t\tif (opts->no_commit)\n-\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n-\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n+\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n \t\telse if (opts->action == REPLAY_PICK)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n-\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n \t\telse if (opts->action == REPLAY_REVERT)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n-\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n \t\telse\n \t\t\tBUG(\"unexpected pick action in print_advice()\");\n \t}\ndiff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\nindex aeab689a98d..43c579ea53a 100755\n--- a/t/t3501-revert-cherry-pick.sh\n+++ b/t/t3501-revert-cherry-pick.sh\n@@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '\n \thint: You can instead skip this commit with \"git revert --skip\".\n \thint: To abort and get back to the state before \"git revert\",\n \thint: run \"git revert --abort\".\n+\thint: Disable this message with \"git config advice.mergeConflict false\"\n \tEOF\n \ttest_commit --append --no-tag \"double-add dream\" dream dream &&\n \ttest_must_fail git revert HEAD^ 2>actual &&\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex c88d597b126..f3947b400a3 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' '\n \thint: You can instead skip this commit with \"git cherry-pick --skip\".\n \thint: To abort and get back to the state before \"git cherry-pick\",\n \thint: run \"git cherry-pick --abort\".\n+\thint: Disable this message with \"git config advice.mergeConflict false\"\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n@@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' \"\n \terror: could not apply \\$picked... picked\n \thint: after resolving the conflicts, mark the corrected paths\n \thint: with 'git add <paths>' or 'git rm <paths>'\n+\thint: Disable this message with \\\"git config advice.mergeConflict false\\\"\n \tEOF\n \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n \n-- \ngitgitgadget\n\n"},{"id":"490347","messageId":"3235542cc6f77779cca1aeff65236e16b0a15d76.1710100261.git.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v2.git.1710100261.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-10T19:51:01Z","receivedAt":"2024-03-10T19:51:06Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"From: Philippe Blain <levraiphilippeblain@gmail.com>\n\nWhen 'git am' or 'git rebase --apply' encounter a conflict, they show a\nmessage instructing the user how to continue the operation. This message\ncan't be disabled.\n\nUse ADVICE_MERGE_CONFLICT introduced in the previous commit to allow\ndisabling it. Update the tests accordingly, as the advice output is now\non stderr instead of stdout. In t4150, redirect stdout to 'out' and\nstderr to 'err', since this is less confusing. In t4254, as we are\ntesting a specific failure mode of 'git am', simply disable the advice.\n\nSigned-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n---\n builtin/am.c          | 14 +++++++++-----\n t/t4150-am.sh         |  8 ++++----\n t/t4254-am-corrupt.sh |  2 +-\n 3 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex d1990d7edcb..0e97b827e4b 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)\n static void NORETURN die_user_resolve(const struct am_state *state)\n {\n \tif (state->resolvemsg) {\n-\t\tprintf_ln(\"%s\", state->resolvemsg);\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", state->resolvemsg);\n \t} else {\n \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n+\t\tstruct strbuf sb = STRBUF_INIT;\n \n-\t\tprintf_ln(_(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n-\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n \n \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n-\t\t\tprintf_ln(_(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n+\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n \n-\t\tprintf_ln(_(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n+\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", sb.buf);\n+\t\tstrbuf_release(&sb);\n \t}\n \n \texit(128);\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 3b125762694..5e2b6c80eae 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -1224,8 +1224,8 @@ test_expect_success 'record as an empty commit when meeting e-mail message that\n \n test_expect_success 'skip an empty patch in the middle of an am session' '\n \tgit checkout empty-commit^ &&\n-\ttest_must_fail git am empty-commit.patch >err &&\n-\tgrep \"Patch is empty.\" err &&\n+\ttest_must_fail git am empty-commit.patch >out 2>err &&\n+\tgrep \"Patch is empty.\" out &&\n \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n \tgit am --skip &&\n \ttest_path_is_missing .git/rebase-apply &&\n@@ -1236,8 +1236,8 @@ test_expect_success 'skip an empty patch in the middle of an am session' '\n \n test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '\n \tgit checkout empty-commit^ &&\n-\ttest_must_fail git am empty-commit.patch >err &&\n-\tgrep \"Patch is empty.\" err &&\n+\ttest_must_fail git am empty-commit.patch >out 2>err &&\n+\tgrep \"Patch is empty.\" out &&\n \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n \tgit am --allow-empty >output &&\n \tgrep \"No changes - recorded it as an empty commit.\" output &&\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 45f1d4f95e5..661feb60709 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -59,7 +59,7 @@ test_expect_success setup '\n # Also, it had the unwanted side-effect of deleting f.\n test_expect_success 'try to apply corrupted patch' '\n \ttest_when_finished \"git am --abort\" &&\n-\ttest_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual &&\n+\ttest_must_fail git -c advice.amWorkDir=false -c advice.mergeConflict=false am bad-patch.diff 2>actual &&\n \techo \"error: git diff header lacks filename information (line 4)\" >expected &&\n \ttest_path_is_file f &&\n \ttest_cmp expected actual\n-- \ngitgitgadget\n"},{"id":"490352","messageId":"15049e66-09b8-4baf-887d-e9118b9cd175@app.fastmail.com","threadId":"61038","inReplyTo":"a2ce6fd24c270fcc89439cd7d119c701dd262ec5.1710100261.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/2] sequencer: allow disabling conflict advice","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2024-03-11T10:29:11Z","receivedAt":"2024-03-11T10:29:37Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"Hi Philippe\n\nOn Sun, Mar 10, 2024, at 20:51, Philippe Blain via GitGitGadget wrote:\n> diff --git a/Documentation/config/advice.txt\n> b/Documentation/config/advice.txt\n> index c7ea70f2e2e..a1178284b23 100644\n> --- a/Documentation/config/advice.txt\n> +++ b/Documentation/config/advice.txt\n> @@ -56,6 +56,8 @@ advice.*::\n>  \t\tAdvice on how to set your identity configuration when\n>  \t\tyour information is guessed from the system username and\n>  \t\tdomain name.\n> +\tmergeConflict::\n> +\t\tAdvice shown when various commands stop because of conflicts.\n\nGiven that topic kh/branch-ref-syntax-advice is in `next`, maybe this\nshould be changed to “Shown when”?[1]\n\n🔗 1: https://lore.kernel.org/git/7017ff3fff773412e8c472d8e59a132b0e8faae7.1709670287.git.code@khaugsbakk.name/\n\n>  \tnestedTag::\n>  \t\tAdvice shown if a user attempts to recursively tag a tag object.\n>  \tpushAlreadyExists::\n"},{"id":"490353","messageId":"f06dcfad-e4b8-4cb7-8728-f5fb018f7be0@gmail.com","threadId":"61038","inReplyTo":"3235542cc6f77779cca1aeff65236e16b0a15d76.1710100261.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-11T10:54:18Z","receivedAt":"2024-03-11T10:54:23Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Philippe\n\nOn 10/03/2024 19:51, Philippe Blain via GitGitGadget wrote:\n> diff --git a/builtin/am.c b/builtin/am.c\n> index d1990d7edcb..0e97b827e4b 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)\n>   static void NORETURN die_user_resolve(const struct am_state *state)\n>   {\n>   \tif (state->resolvemsg) {\n> -\t\tprintf_ln(\"%s\", state->resolvemsg);\n> +\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", state->resolvemsg);\n>   \t} else {\n>   \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n> +\t\tstruct strbuf sb = STRBUF_INIT;\n>   \n> -\t\tprintf_ln(_(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n> -\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n> +\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n> +\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n\nI think you need to append \"\\n\" to the message strings here (and below) \nto match the behavior of printf_ln().\n\nApart from that both patches look good to me, thanks for re-rolling. It \nis a bit surprising that we don't need to update any rebase tests. I \nhaven't checked but I guess either we're not testing this advice when \nrebasing or we're using a grep expression that is vague enough not to be \naffected.\n\nBest Wishes\n\nPhillip\n\n>   \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n>   \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n>   \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n> -\t\t\tprintf_ln(_(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n> +\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n>   \n> -\t\tprintf_ln(_(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n> +\t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n> +\n> +\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", sb.buf);\n> +\t\tstrbuf_release(&sb);\n>   \t}message instructing the user how to continue the operation. This message\n>   \n>   \texit(128);\n> diff --git a/t/t4150-am.sh b/t/t4150-am.sh\n> index 3b125762694..5e2b6c80eae 100755\n> --- a/t/t4150-am.sh\n> +++ b/t/t4150-am.sh\n> @@ -1224,8 +1224,8 @@ test_expect_success 'record as an empty commit when meeting e-mail message that\n>   \n>   test_expect_success 'skip an empty patch in the middle of an am session' '\n>   \tgit checkout empty-commit^ &&\n> -\ttest_must_fail git am empty-commit.patch >err &&\n> -\tgrep \"Patch is empty.\" err &&\n> +\ttest_must_fail git am empty-commit.patch >out 2>err &&\n> +\tgrep \"Patch is empty.\" out &&\n>   \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n>   \tgit am --skip &&\n>   \ttest_path_is_missing .git/rebase-apply &&\n> @@ -1236,8 +1236,8 @@ test_expect_success 'skip an empty patch in the middle of an am session' '\n>   \n>   test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '\n>   \tgit checkout empty-commit^ &&\n> -\ttest_must_fail git am empty-commit.patch >err &&\n> -\tgrep \"Patch is empty.\" err &&\n> +\ttest_must_fail git am empty-commit.patch >out 2>err &&\n> +\tgrep \"Patch is empty.\" out &&\n>   \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n>   \tgit am --allow-empty >output &&\n>   \tgrep \"No changes - recorded it as an empty commit.\" output &&\n> diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\n> index 45f1d4f95e5..661feb60709 100755\n> --- a/t/t4254-am-corrupt.sh\n> +++ b/t/t4254-am-corrupt.sh\n> @@ -59,7 +59,7 @@ test_expect_success setup '\n>   # Also, it had the unwanted side-effect of deleting f.\n>   test_expect_success 'try to apply corrupted patch' '\n>   \ttest_when_finished \"git am --abort\" &&\n> -\ttest_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual &&\n> +\ttest_must_fail git -c advice.amWorkDir=false -c advice.mergeConflict=false am bad-patch.diff 2>actual &&\n>   \techo \"error: git diff header lacks filename information (line 4)\" >expected &&\n>   \ttest_path_is_file f &&\n>   \ttest_cmp expected actual\n"},{"id":"490368","messageId":"xmqq5xxsu1z5.fsf@gitster.g","threadId":"61038","inReplyTo":"f06dcfad-e4b8-4cb7-8728-f5fb018f7be0@gmail.com","subject":"Re: [PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-11T17:12:30Z","receivedAt":"2024-03-11T17:12:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"phillip.wood123@gmail.com writes:\n\n> Hi Philippe\n>\n> On 10/03/2024 19:51, Philippe Blain via GitGitGadget wrote:\n>> diff --git a/builtin/am.c b/builtin/am.c\n>> index d1990d7edcb..0e97b827e4b 100644\n>> --- a/builtin/am.c\n>> +++ b/builtin/am.c\n>> @@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)\n>>   static void NORETURN die_user_resolve(const struct am_state *state)\n>>   {\n>>   \tif (state->resolvemsg) {\n>> -\t\tprintf_ln(\"%s\", state->resolvemsg);\n>> +\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", state->resolvemsg);\n>>   \t} else {\n>>   \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n>> +\t\tstruct strbuf sb = STRBUF_INIT;\n>>   -\t\tprintf_ln(_(\"When you have resolved this problem, run\n>> \\\"%s --continue\\\".\"), cmdline);\n>> -\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>> +\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n>> +\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>\n> I think you need to append \"\\n\" to the message strings here (and\n> below) to match the behavior of printf_ln().\n\nGood eyes.  You'll get the final \"\\n\" but the line breaks inside the\nparagraph you give to advise*() functions are your responsibility.\nEven though advice.c:vadvise() handles multi-line message better\n(unlike usage.c:vreportf() that is used for error() and die()) by\ngiving a line header for each line of the message, we do not wrap\nlines at runtime.\n\n> Apart from that both patches look good to me, thanks for\n> re-rolling. It is a bit surprising that we don't need to update any\n\nThanks, both, and indeed it is a bit surprising.\n\n> rebase tests. I haven't checked but I guess either we're not testing\n> this advice when rebasing or we're using a grep expression that is\n> vague enough not to be affected.\n"},{"id":"490374","messageId":"xmqq1q8gsloz.fsf@gitster.g","threadId":"61038","inReplyTo":"xmqq5xxsu1z5.fsf@gitster.g","subject":"Re: [PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-11T17:49:32Z","receivedAt":"2024-03-11T17:49:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> I think you need to append \"\\n\" to the message strings here (and\n>> below) to match the behavior of printf_ln().\n>\n> Good eyes.  You'll get the final \"\\n\" but the line breaks inside the\n> paragraph you give to advise*() functions are your responsibility.\n> Even though advice.c:vadvise() handles multi-line message better\n> (unlike usage.c:vreportf() that is used for error() and die()) by\n> giving a line header for each line of the message, we do not wrap\n> lines at runtime.\n\nPerhaps something like this.\n\nThe overly long lines are getting a bit annoying but I do not\noffhand think of a good way to shorten them.\n\nAlso, having to assemble the message in a buffer and emit them all\nonce with (\"%s\" % sb.buf) is a highly annoying pattern.  Perhaps\ngiven enough examples, somebody will come up with a simpler API to\ndo the same thing, but that is not in the scope of this series.\n\n builtin/am.c | 7 +++----\n 1 file changed, 3 insertions(+), 4 deletions(-)\n\ndiff --git i/builtin/am.c w/builtin/am.c\nindex 0e97b827e4..227036d732 100644\n--- i/builtin/am.c\n+++ w/builtin/am.c\n@@ -1155,14 +1155,13 @@ static void NORETURN die_user_resolve(const struct am_state *state)\n \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n \t\tstruct strbuf sb = STRBUF_INIT;\n \n-\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n-\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\\n\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\\n\"), cmdline);\n \n \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n-\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n-\n+\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\\n\"), cmdline);\n \t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n \n \t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", sb.buf);\n"},{"id":"490396","messageId":"4e1abd12-d73f-41b2-a334-036be9093485@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v2.git.1710100261.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] Allow disabling advice shown after merge conflicts","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-11T20:58:52Z","receivedAt":"2024-03-11T20:59:16Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On Sun, Mar 10, 2024 at 07:50:59PM +0000, Philippe Blain via GitGitGadget wrote:\n\n> Range-diff vs v1:\n> \n>  1:  e929d3381cf ! 1:  a2ce6fd24c2 sequencer: allow disabling conflict advice\n\n[...]\n\n>        ## advice.c ##\n>       @@ advice.c: static struct {\n>      - \t[ADVICE_RESET_NO_REFRESH_WARNING]\t\t= { \"resetNoRefresh\" },\n>      - \t[ADVICE_RESOLVE_CONFLICT]\t\t\t= { \"resolveConflict\" },\n>      - \t[ADVICE_RM_HINTS]\t\t\t\t= { \"rmHints\" },\n>      -+\t[ADVICE_SEQUENCER_CONFLICT]                     = { \"sequencerConflict\" },\n>      - \t[ADVICE_SEQUENCER_IN_USE]\t\t\t= { \"sequencerInUse\" },\n>      - \t[ADVICE_SET_UPSTREAM_FAILURE]\t\t\t= { \"setUpstreamFailure\" },\n>      - \t[ADVICE_SKIPPED_CHERRY_PICKS]\t\t\t= { \"skippedCherryPicks\" },\n>      + \t[ADVICE_GRAFT_FILE_DEPRECATED]\t\t\t= { \"graftFileDeprecated\" },\n>      + \t[ADVICE_IGNORED_HOOK]\t\t\t\t= { \"ignoredHook\" },\n>      + \t[ADVICE_IMPLICIT_IDENTITY]\t\t\t= { \"implicitIdentity\" },\n>      ++\t[ADVICE_MERGE_CONFLICT]\t\t\t\t= { \"mergeConflict\" },\n>      + \t[ADVICE_NESTED_TAG]\t\t\t\t= { \"nestedTag\" },\n>      + \t[ADVICE_OBJECT_NAME_WARNING]\t\t\t= { \"objectNameWarning\" },\n>      + \t[ADVICE_PUSH_ALREADY_EXISTS]\t\t\t= { \"pushAlreadyExists\" },\n\nYou rename ADVICE_SEQUENCER_CONFLICT to ADVICE_MERGE_CONFLICT and place\nthe new name in the correct position, alphabetically.  Nice.\n\n>        ## advice.h ##\n>       @@ advice.h: enum advice_type {\n>      - \tADVICE_RESOLVE_CONFLICT,\n>      - \tADVICE_RM_HINTS,\n>      - \tADVICE_SEQUENCER_IN_USE,\n>      -+\tADVICE_SEQUENCER_CONFLICT,\n>      - \tADVICE_SET_UPSTREAM_FAILURE,\n>      - \tADVICE_SKIPPED_CHERRY_PICKS,\n>      - \tADVICE_STATUS_AHEAD_BEHIND_WARNING,\n>      + \tADVICE_IGNORED_HOOK,\n>      + \tADVICE_IMPLICIT_IDENTITY,\n>      + \tADVICE_NESTED_TAG,\n>      ++\tADVICE_MERGE_CONFLICT,\n>      + \tADVICE_OBJECT_NAME_WARNING,\n>      + \tADVICE_PUSH_ALREADY_EXISTS,\n>      + \tADVICE_PUSH_FETCH_FIRST,\n\nHere, I assume you're trying to place the new name correctly too.\nHowever, I see that it's in the wrong place.  It initially caught my\nattention, but then I realize that the list is not sorted.  So it's\nunderstandable.\n\nMaybe you want to sort the list as a preparatory patch in this series\nand so we'll avoid this kind of mistakes.\n\nOf course, this does not deserve a reroll.  We can do it in a future\nseries when the dust settles.\n"},{"id":"490796","messageId":"6051365b-7ebd-b63b-2ece-4fc072a001e5@gmail.com","threadId":"61038","inReplyTo":"15049e66-09b8-4baf-887d-e9118b9cd175@app.fastmail.com","subject":"Re: [PATCH v2 1/2] sequencer: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-16T19:33:57Z","receivedAt":"2024-03-16T19:34:00Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Kristoffer,\n\nLe 2024-03-11 à 06:29, Kristoffer Haugsbakk a écrit :\n> Hi Philippe\n> \n> On Sun, Mar 10, 2024, at 20:51, Philippe Blain via GitGitGadget wrote:\n>> diff --git a/Documentation/config/advice.txt\n>> b/Documentation/config/advice.txt\n>> index c7ea70f2e2e..a1178284b23 100644\n>> --- a/Documentation/config/advice.txt\n>> +++ b/Documentation/config/advice.txt\n>> @@ -56,6 +56,8 @@ advice.*::\n>>  \t\tAdvice on how to set your identity configuration when\n>>  \t\tyour information is guessed from the system username and\n>>  \t\tdomain name.\n>> +\tmergeConflict::\n>> +\t\tAdvice shown when various commands stop because of conflicts.\n> \n> Given that topic kh/branch-ref-syntax-advice is in `next`, maybe this\n> should be changed to “Shown when”?[1]\n> \n> 🔗 1: https://lore.kernel.org/git/7017ff3fff773412e8c472d8e59a132b0e8faae7.1709670287.git.code@khaugsbakk.name/\n\nThanks for the pointer, I will change that for uniformity\nin that section of the doc.\n\nCheers,\nPhilippe.\n"},{"id":"490797","messageId":"1961b9dc-e372-b0f9-9185-a1c11d32f1b3@gmail.com","threadId":"61038","inReplyTo":"xmqq1q8gsloz.fsf@gitster.g","subject":"Re: [PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-16T19:44:49Z","receivedAt":"2024-03-16T19:44:52Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Phillip and Junio,\n\nLe 2024-03-11 à 13:49, Junio C Hamano a écrit :\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>>> I think you need to append \"\\n\" to the message strings here (and\n>>> below) to match the behavior of printf_ln().\n>>\n>> Good eyes.  You'll get the final \"\\n\" but the line breaks inside the\n>> paragraph you give to advise*() functions are your responsibility.\n>> Even though advice.c:vadvise() handles multi-line message better\n>> (unlike usage.c:vreportf() that is used for error() and die()) by\n>> giving a line header for each line of the message, we do not wrap\n>> lines at runtime.\n> \n> Perhaps something like this.\n\nThanks Phillip for noticing, and Junio for the fix. I should have looked\nat the output, apologies. I made sure that the test passed but since \nt/t4150-am.sh only checks for the \"To record the empty patch as an empty commit\"\nstring, it still passed despite the missing newlines.\n\nJust a note if it helps anyone: I cherry-picked Junio's fixes using:\n\n   b4 shazam -P _ '<xmqq1q8gsloz.fsf@gitster.g>'\n\n\nCheers,\n\nPhilippe.\n"},{"id":"490798","messageId":"c9b3714b-e009-5c86-3cfa-993be018dd01@gmail.com","threadId":"61038","inReplyTo":"xmqq5xxsu1z5.fsf@gitster.g","subject":"Re: [PATCH v2 2/2] builtin/am: allow disabling conflict advice","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-16T20:01:05Z","receivedAt":"2024-03-16T20:01:07Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"\n\nLe 2024-03-11 à 13:12, Junio C Hamano a écrit :\n> phillip.wood123@gmail.com writes:\n> \n>> Hi Philippe\n>>\n>> On 10/03/2024 19:51, Philippe Blain via GitGitGadget wrote:\n>>> diff --git a/builtin/am.c b/builtin/am.c\n>>> index d1990d7edcb..0e97b827e4b 100644\n>>> --- a/builtin/am.c\n>>> +++ b/builtin/am.c\n>>> @@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)\n>>>   static void NORETURN die_user_resolve(const struct am_state *state)\n>>>   {\n>>>   \tif (state->resolvemsg) {\n>>> -\t\tprintf_ln(\"%s\", state->resolvemsg);\n>>> +\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", state->resolvemsg);\n>>>   \t} else {\n>>>   \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n>>> +\t\tstruct strbuf sb = STRBUF_INIT;\n>>>   -\t\tprintf_ln(_(\"When you have resolved this problem, run\n>>> \\\"%s --continue\\\".\"), cmdline);\n>>> -\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>>> +\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n>>> +\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>>\n>> I think you need to append \"\\n\" to the message strings here (and\n>> below) to match the behavior of printf_ln().\n> \n> Good eyes.  You'll get the final \"\\n\" but the line breaks inside the\n> paragraph you give to advise*() functions are your responsibility.\n> Even though advice.c:vadvise() handles multi-line message better\n> (unlike usage.c:vreportf() that is used for error() and die()) by\n> giving a line header for each line of the message, we do not wrap\n> lines at runtime.\n> \n>> Apart from that both patches look good to me, thanks for\n>> re-rolling. It is a bit surprising that we don't need to update any\n> \n> Thanks, both, and indeed it is a bit surprising.\n> \n>> rebase tests. I haven't checked but I guess either we're not testing\n>> this advice when rebasing or we're using a grep expression that is\n>> vague enough not to be affected.\n\nWe are not testing this advice when rebasing _with the apply backend_. \nWe are testing it with the merge backend (in t5520-pull.sh) but we are \nonly grepping stderr for  \"Resolve all conflicts manually\" so I did not \nhave to change anything. I'll add that to the commit message for completeness.\n\nWe were testing the apply backend through the same test before 2ac0d6273f \n(rebase: change the default backend from \"am\" to \"merge\", 2020-02-15).\n\nThanks,\nPhilippe.\n"},{"id":"490799","messageId":"f773d6d8-ad1b-dec7-1ba1-741af497bccc@gmail.com","threadId":"61038","inReplyTo":"4e1abd12-d73f-41b2-a334-036be9093485@gmail.com","subject":"Re: [PATCH v2 0/2] Allow disabling advice shown after merge conflicts","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2024-03-16T20:33:03Z","receivedAt":"2024-03-16T20:33:05Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Rubén,\n\nLe 2024-03-11 à 16:58, Rubén Justo a écrit :\n> On Sun, Mar 10, 2024 at 07:50:59PM +0000, Philippe Blain via GitGitGadget wrote:\n> \n> \n>>        ## advice.h ##\n>>       @@ advice.h: enum advice_type {\n>>      - \tADVICE_RESOLVE_CONFLICT,\n>>      - \tADVICE_RM_HINTS,\n>>      - \tADVICE_SEQUENCER_IN_USE,\n>>      -+\tADVICE_SEQUENCER_CONFLICT,\n>>      - \tADVICE_SET_UPSTREAM_FAILURE,\n>>      - \tADVICE_SKIPPED_CHERRY_PICKS,\n>>      - \tADVICE_STATUS_AHEAD_BEHIND_WARNING,\n>>      + \tADVICE_IGNORED_HOOK,\n>>      + \tADVICE_IMPLICIT_IDENTITY,\n>>      + \tADVICE_NESTED_TAG,\n>>      ++\tADVICE_MERGE_CONFLICT,\n>>      + \tADVICE_OBJECT_NAME_WARNING,\n>>      + \tADVICE_PUSH_ALREADY_EXISTS,\n>>      + \tADVICE_PUSH_FETCH_FIRST,\n> \n> Here, I assume you're trying to place the new name correctly too.\n> However, I see that it's in the wrong place.  It initially caught my\n> attention, but then I realize that the list is not sorted.  So it's\n> understandable.\n> \n> Maybe you want to sort the list as a preparatory patch in this series\n> and so we'll avoid this kind of mistakes.\n> \n> Of course, this does not deserve a reroll.  We can do it in a future\n> series when the dust settles.\n\nI fixed this to put it in the correct order.\n\nThanks,\n\nPhilippe.\n"},{"id":"490804","messageId":"pull.1682.v3.git.1710623790.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v2.git.1710100261.gitgitgadget@gmail.com","subject":"[PATCH v3 0/2] Allow disabling advice shown after merge conflicts","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-16T21:16:28Z","receivedAt":"2024-03-16T21:16:35Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"This series introduces a new config 'advice.mergeConflict' and uses it to\nallow disabling the advice shown when 'git rebase', 'git cherry-pick', 'git\nrevert', 'git rebase --apply' and 'git am' stop because of conflicts.\n\nThanks everyone for the reviews!\n\nChanges since v2:\n\n * expanded the commit messages to explain why the tests for 'git rebase' do\n   not need to be adjusted\n * adjusted the wording of the new 'advice.mergeConflict' in the doc, as\n   suggested by Kristoffer for uniformity with his series which is already\n   merged to 'master' (b09a8839a4 (Merge branch\n   'kh/branch-ref-syntax-advice', 2024-03-15)).\n * checked all new output manually and consequently adjusted the code in 1/2\n   to avoid a lonely 'hint: ' line.\n * adjusted the addition in advice.h in 1/2 to put the new enum\n   alphabetically, as noticed by Rubén.\n * added misssing newlines in 2/2 as noticed by Phillip and tweaked by\n   Junio.\n * rebased on master (2953d95d40 (The eighth batch, 2024-03-15)), to avoid\n   conflicts in 'Documentation/config/advice.txt' due to Kristoffer's merged\n   series\n\nChanges since v1:\n\n * renamed the new advice to 'advice.mergeConflict' to make it non-sequencer\n   specific\n * added 2/2 which uses the advice in builtin/am, which covers 'git rebase\n   --apply' and 'git am'\n\nNote that the code path where 'git rebase --apply' stops because of\nconflicts is not covered by the tests but I tested it manually using this\ndiff:\n\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 47534f1062..34eac2e6f4 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -374,7 +374,7 @@ test_pull_autostash_fail ()\n     echo conflicting >>seq.txt &&\n     test_tick &&\n     git commit -m \"Create conflict\" seq.txt &&\n-\ttest_must_fail git pull --rebase . seq 2>err >out &&\n+\ttest_must_fail git -c rebase.backend=apply pull --rebase . seq 2>err >out &&\n     test_grep \"Resolve all conflicts manually\" err\n '\n\n\nPhilippe Blain (2):\n  sequencer: allow disabling conflict advice\n  builtin/am: allow disabling conflict advice\n\n Documentation/config/advice.txt |  2 ++\n advice.c                        |  1 +\n advice.h                        |  1 +\n builtin/am.c                    | 14 +++++++++-----\n sequencer.c                     | 33 ++++++++++++++++++---------------\n t/t3501-revert-cherry-pick.sh   |  1 +\n t/t3507-cherry-pick-conflict.sh |  2 ++\n t/t4150-am.sh                   |  8 ++++----\n t/t4254-am-corrupt.sh           |  2 +-\n 9 files changed, 39 insertions(+), 25 deletions(-)\n\n\nbase-commit: 2953d95d402b6bff1a59c4712f4d46f1b9ea137f\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1682%2Fphil-blain%2Fsequencer-conflict-advice-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1682/phil-blain/sequencer-conflict-advice-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/1682\n\nRange-diff vs v2:\n\n 1:  a2ce6fd24c2 ! 1:  6005c1e9890 sequencer: allow disabling conflict advice\n     @@ Commit message\n          merge conflict through a new config 'advice.mergeConflict', which is\n          named generically such that it can be used by other commands eventually.\n      \n     +    Remove that final '\\n' in the first hunk in sequencer.c to avoid an\n     +    otherwise empty 'hint: ' line before the line 'hint: Disable this\n     +    message with \"git config advice.mergeConflict false\"' which is\n     +    automatically added by 'advise_if_enabled'.\n     +\n          Note that we use 'advise_if_enabled' for each message in the second hunk\n          in sequencer.c, instead of using 'if (show_hints &&\n          advice_enabled(...)', because the former instructs the user how to\n     @@ Commit message\n      \n          Update the tests accordingly. Note that the body of the second test in\n          t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\n     -    escape them in the added line.\n     +    escape them in the added line. Note that t5520-pull.sh, which checks\n     +    that we display the advice for 'git rebase' (via 'git pull --rebase')\n     +    does not have to be updated because it only greps for a specific line in\n     +    the advice message.\n      \n          Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n      \n       ## Documentation/config/advice.txt ##\n      @@ Documentation/config/advice.txt: advice.*::\n     - \t\tAdvice on how to set your identity configuration when\n     - \t\tyour information is guessed from the system username and\n     - \t\tdomain name.\n     + \t\tShown when the user's information is guessed from the\n     + \t\tsystem username and domain name, to tell the user how to\n     + \t\tset their identity configuration.\n      +\tmergeConflict::\n     -+\t\tAdvice shown when various commands stop because of conflicts.\n     ++\t\tShown when various commands stop because of conflicts.\n       \tnestedTag::\n     - \t\tAdvice shown if a user attempts to recursively tag a tag object.\n     + \t\tShown when a user attempts to recursively tag a tag object.\n       \tpushAlreadyExists::\n      \n       ## advice.c ##\n     @@ advice.c: static struct {\n      \n       ## advice.h ##\n      @@ advice.h: enum advice_type {\n     + \tADVICE_GRAFT_FILE_DEPRECATED,\n       \tADVICE_IGNORED_HOOK,\n       \tADVICE_IMPLICIT_IDENTITY,\n     - \tADVICE_NESTED_TAG,\n      +\tADVICE_MERGE_CONFLICT,\n     + \tADVICE_NESTED_TAG,\n       \tADVICE_OBJECT_NAME_WARNING,\n       \tADVICE_PUSH_ALREADY_EXISTS,\n     - \tADVICE_PUSH_FETCH_FIRST,\n      \n       ## sequencer.c ##\n      @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n       \n       \tif (msg) {\n      -\t\tadvise(\"%s\\n\", msg);\n     -+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\\n\", msg);\n     ++\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", msg);\n       \t\t/*\n       \t\t * A conflict has occurred but the porcelain\n       \t\t * (typically rebase --interactive) wants to take care\n 2:  3235542cc6f ! 2:  73d07c8b6a7 builtin/am: allow disabling conflict advice\n     @@ Commit message\n          on stderr instead of stdout. In t4150, redirect stdout to 'out' and\n          stderr to 'err', since this is less confusing. In t4254, as we are\n          testing a specific failure mode of 'git am', simply disable the advice.\n     +    Note that we are not testing that this advice is shown in 'git rebase'\n     +    for the apply backend since 2ac0d6273f (rebase: change the default\n     +    backend from \"am\" to \"merge\", 2020-02-15).\n      \n     +    Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n     +    Helped-by: Junio C Hamano <gitster@pobox.com>\n          Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n      \n       ## builtin/am.c ##\n     @@ builtin/am.c: static const char *msgnum(const struct am_state *state)\n       \n      -\t\tprintf_ln(_(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n      -\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n     -+\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n     -+\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n     ++\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\\n\"), cmdline);\n     ++\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\\n\"), cmdline);\n       \n       \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n       \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n       \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n      -\t\t\tprintf_ln(_(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n     -+\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n     ++\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\\n\"), cmdline);\n       \n      -\t\tprintf_ln(_(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n      +\t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n\n-- \ngitgitgadget\n"},{"id":"490805","messageId":"6005c1e98905c7a97d061a0034a5461052947f5a.1710623790.git.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v3.git.1710623790.gitgitgadget@gmail.com","subject":"[PATCH v3 1/2] sequencer: allow disabling conflict advice","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-16T21:16:29Z","receivedAt":"2024-03-16T21:16:35Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"From: Philippe Blain <levraiphilippeblain@gmail.com>\n\nAllow disabling the advice shown when a squencer operation results in a\nmerge conflict through a new config 'advice.mergeConflict', which is\nnamed generically such that it can be used by other commands eventually.\n\nRemove that final '\\n' in the first hunk in sequencer.c to avoid an\notherwise empty 'hint: ' line before the line 'hint: Disable this\nmessage with \"git config advice.mergeConflict false\"' which is\nautomatically added by 'advise_if_enabled'.\n\nNote that we use 'advise_if_enabled' for each message in the second hunk\nin sequencer.c, instead of using 'if (show_hints &&\nadvice_enabled(...)', because the former instructs the user how to\ndisable the advice, which is more user-friendly.\n\nUpdate the tests accordingly. Note that the body of the second test in\nt3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\nescape them in the added line. Note that t5520-pull.sh, which checks\nthat we display the advice for 'git rebase' (via 'git pull --rebase')\ndoes not have to be updated because it only greps for a specific line in\nthe advice message.\n\nSigned-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n---\n Documentation/config/advice.txt |  2 ++\n advice.c                        |  1 +\n advice.h                        |  1 +\n sequencer.c                     | 33 ++++++++++++++++++---------------\n t/t3501-revert-cherry-pick.sh   |  1 +\n t/t3507-cherry-pick-conflict.sh |  2 ++\n 6 files changed, 25 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt\nindex f8334116536..0e35ae5240f 100644\n--- a/Documentation/config/advice.txt\n+++ b/Documentation/config/advice.txt\n@@ -56,6 +56,8 @@ advice.*::\n \t\tShown when the user's information is guessed from the\n \t\tsystem username and domain name, to tell the user how to\n \t\tset their identity configuration.\n+\tmergeConflict::\n+\t\tShown when various commands stop because of conflicts.\n \tnestedTag::\n \t\tShown when a user attempts to recursively tag a tag object.\n \tpushAlreadyExists::\ndiff --git a/advice.c b/advice.c\nindex b0e05506871..d19648b7f88 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -57,6 +57,7 @@ static struct {\n \t[ADVICE_GRAFT_FILE_DEPRECATED]\t\t\t= { \"graftFileDeprecated\" },\n \t[ADVICE_IGNORED_HOOK]\t\t\t\t= { \"ignoredHook\" },\n \t[ADVICE_IMPLICIT_IDENTITY]\t\t\t= { \"implicitIdentity\" },\n+\t[ADVICE_MERGE_CONFLICT]\t\t\t\t= { \"mergeConflict\" },\n \t[ADVICE_NESTED_TAG]\t\t\t\t= { \"nestedTag\" },\n \t[ADVICE_OBJECT_NAME_WARNING]\t\t\t= { \"objectNameWarning\" },\n \t[ADVICE_PUSH_ALREADY_EXISTS]\t\t\t= { \"pushAlreadyExists\" },\ndiff --git a/advice.h b/advice.h\nindex bf630ee3ac3..c8d29f97f39 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -25,6 +25,7 @@ enum advice_type {\n \tADVICE_GRAFT_FILE_DEPRECATED,\n \tADVICE_IGNORED_HOOK,\n \tADVICE_IMPLICIT_IDENTITY,\n+\tADVICE_MERGE_CONFLICT,\n \tADVICE_NESTED_TAG,\n \tADVICE_OBJECT_NAME_WARNING,\n \tADVICE_PUSH_ALREADY_EXISTS,\ndiff --git a/sequencer.c b/sequencer.c\nindex ea1441e6174..019f0a0b27a 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -467,7 +467,7 @@ static void print_advice(struct repository *r, int show_hint,\n \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n \n \tif (msg) {\n-\t\tadvise(\"%s\\n\", msg);\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", msg);\n \t\t/*\n \t\t * A conflict has occurred but the porcelain\n \t\t * (typically rebase --interactive) wants to take care\n@@ -480,22 +480,25 @@ static void print_advice(struct repository *r, int show_hint,\n \n \tif (show_hint) {\n \t\tif (opts->no_commit)\n-\t\t\tadvise(_(\"after resolving the conflicts, mark the corrected paths\\n\"\n-\t\t\t\t \"with 'git add <paths>' or 'git rm <paths>'\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"after resolving the conflicts, mark the corrected paths\\n\"\n+\t\t\t\t\t    \"with 'git add <paths>' or 'git rm <paths>'\"));\n \t\telse if (opts->action == REPLAY_PICK)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git cherry-pick --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n-\t\t\t\t \"run \\\"git cherry-pick --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git cherry-pick --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git cherry-pick --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git cherry-pick\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git cherry-pick --abort\\\".\"));\n \t\telse if (opts->action == REPLAY_REVERT)\n-\t\t\tadvise(_(\"After resolving the conflicts, mark them with\\n\"\n-\t\t\t\t \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n-\t\t\t\t \"\\\"git revert --continue\\\".\\n\"\n-\t\t\t\t \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n-\t\t\t\t \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n-\t\t\t\t \"run \\\"git revert --abort\\\".\"));\n+\t\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT,\n+\t\t\t\t\t  _(\"After resolving the conflicts, mark them with\\n\"\n+\t\t\t\t\t    \"\\\"git add/rm <pathspec>\\\", then run\\n\"\n+\t\t\t\t\t    \"\\\"git revert --continue\\\".\\n\"\n+\t\t\t\t\t    \"You can instead skip this commit with \\\"git revert --skip\\\".\\n\"\n+\t\t\t\t\t    \"To abort and get back to the state before \\\"git revert\\\",\\n\"\n+\t\t\t\t\t    \"run \\\"git revert --abort\\\".\"));\n \t\telse\n \t\t\tBUG(\"unexpected pick action in print_advice()\");\n \t}\ndiff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\nindex aeab689a98d..43c579ea53a 100755\n--- a/t/t3501-revert-cherry-pick.sh\n+++ b/t/t3501-revert-cherry-pick.sh\n@@ -170,6 +170,7 @@ test_expect_success 'advice from failed revert' '\n \thint: You can instead skip this commit with \"git revert --skip\".\n \thint: To abort and get back to the state before \"git revert\",\n \thint: run \"git revert --abort\".\n+\thint: Disable this message with \"git config advice.mergeConflict false\"\n \tEOF\n \ttest_commit --append --no-tag \"double-add dream\" dream dream &&\n \ttest_must_fail git revert HEAD^ 2>actual &&\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex c88d597b126..f3947b400a3 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -60,6 +60,7 @@ test_expect_success 'advice from failed cherry-pick' '\n \thint: You can instead skip this commit with \"git cherry-pick --skip\".\n \thint: To abort and get back to the state before \"git cherry-pick\",\n \thint: run \"git cherry-pick --abort\".\n+\thint: Disable this message with \"git config advice.mergeConflict false\"\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n@@ -74,6 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' \"\n \terror: could not apply \\$picked... picked\n \thint: after resolving the conflicts, mark the corrected paths\n \thint: with 'git add <paths>' or 'git rm <paths>'\n+\thint: Disable this message with \\\"git config advice.mergeConflict false\\\"\n \tEOF\n \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n \n-- \ngitgitgadget\n\n"},{"id":"490806","messageId":"73d07c8b6a7fc56510798e7e146cb8b14ad558f7.1710623790.git.gitgitgadget@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v3.git.1710623790.gitgitgadget@gmail.com","subject":"[PATCH v3 2/2] builtin/am: allow disabling conflict advice","fromName":"Philippe Blain via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2024-03-16T21:16:30Z","receivedAt":"2024-03-16T21:16:37Z","isPatch":true,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"From: Philippe Blain <levraiphilippeblain@gmail.com>\n\nWhen 'git am' or 'git rebase --apply' encounter a conflict, they show a\nmessage instructing the user how to continue the operation. This message\ncan't be disabled.\n\nUse ADVICE_MERGE_CONFLICT introduced in the previous commit to allow\ndisabling it. Update the tests accordingly, as the advice output is now\non stderr instead of stdout. In t4150, redirect stdout to 'out' and\nstderr to 'err', since this is less confusing. In t4254, as we are\ntesting a specific failure mode of 'git am', simply disable the advice.\nNote that we are not testing that this advice is shown in 'git rebase'\nfor the apply backend since 2ac0d6273f (rebase: change the default\nbackend from \"am\" to \"merge\", 2020-02-15).\n\nHelped-by: Phillip Wood <phillip.wood@dunelm.org.uk>\nHelped-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n---\n builtin/am.c          | 14 +++++++++-----\n t/t4150-am.sh         |  8 ++++----\n t/t4254-am-corrupt.sh |  2 +-\n 3 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex d1990d7edcb..d87847205c7 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)\n static void NORETURN die_user_resolve(const struct am_state *state)\n {\n \tif (state->resolvemsg) {\n-\t\tprintf_ln(\"%s\", state->resolvemsg);\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", state->resolvemsg);\n \t} else {\n \t\tconst char *cmdline = state->interactive ? \"git am -i\" : \"git am\";\n+\t\tstruct strbuf sb = STRBUF_INIT;\n \n-\t\tprintf_ln(_(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n-\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\\n\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\\n\"), cmdline);\n \n \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n-\t\t\tprintf_ln(_(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n+\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\\n\"), cmdline);\n \n-\t\tprintf_ln(_(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n+\t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n+\n+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", sb.buf);\n+\t\tstrbuf_release(&sb);\n \t}\n \n \texit(128);\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 3b125762694..5e2b6c80eae 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -1224,8 +1224,8 @@ test_expect_success 'record as an empty commit when meeting e-mail message that\n \n test_expect_success 'skip an empty patch in the middle of an am session' '\n \tgit checkout empty-commit^ &&\n-\ttest_must_fail git am empty-commit.patch >err &&\n-\tgrep \"Patch is empty.\" err &&\n+\ttest_must_fail git am empty-commit.patch >out 2>err &&\n+\tgrep \"Patch is empty.\" out &&\n \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n \tgit am --skip &&\n \ttest_path_is_missing .git/rebase-apply &&\n@@ -1236,8 +1236,8 @@ test_expect_success 'skip an empty patch in the middle of an am session' '\n \n test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '\n \tgit checkout empty-commit^ &&\n-\ttest_must_fail git am empty-commit.patch >err &&\n-\tgrep \"Patch is empty.\" err &&\n+\ttest_must_fail git am empty-commit.patch >out 2>err &&\n+\tgrep \"Patch is empty.\" out &&\n \tgrep \"To record the empty patch as an empty commit, run \\\"git am --allow-empty\\\".\" err &&\n \tgit am --allow-empty >output &&\n \tgrep \"No changes - recorded it as an empty commit.\" output &&\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 45f1d4f95e5..661feb60709 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -59,7 +59,7 @@ test_expect_success setup '\n # Also, it had the unwanted side-effect of deleting f.\n test_expect_success 'try to apply corrupted patch' '\n \ttest_when_finished \"git am --abort\" &&\n-\ttest_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual &&\n+\ttest_must_fail git -c advice.amWorkDir=false -c advice.mergeConflict=false am bad-patch.diff 2>actual &&\n \techo \"error: git diff header lacks filename information (line 4)\" >expected &&\n \ttest_path_is_file f &&\n \ttest_cmp expected actual\n-- \ngitgitgadget\n"},{"id":"490881","messageId":"xmqq5xxjjyd3.fsf@gitster.g","threadId":"61038","inReplyTo":"pull.1682.v3.git.1710623790.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/2] Allow disabling advice shown after merge conflicts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-18T16:31:04Z","receivedAt":"2024-03-18T16:31:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Philippe Blain via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> This series introduces a new config 'advice.mergeConflict' and uses it to\n> allow disabling the advice shown when 'git rebase', 'git cherry-pick', 'git\n> revert', 'git rebase --apply' and 'git am' stop because of conflicts.\n>\n> Thanks everyone for the reviews!\n>\n> Changes since v2:\n>\n>  * expanded the commit messages to explain why the tests for 'git rebase' do\n>    not need to be adjusted\n>  * adjusted the wording of the new 'advice.mergeConflict' in the doc, as\n>    suggested by Kristoffer for uniformity with his series which is already\n>    merged to 'master' (b09a8839a4 (Merge branch\n>    'kh/branch-ref-syntax-advice', 2024-03-15)).\n>  * checked all new output manually and consequently adjusted the code in 1/2\n>    to avoid a lonely 'hint: ' line.\n>  * adjusted the addition in advice.h in 1/2 to put the new enum\n>    alphabetically, as noticed by Rubén.\n>  * added misssing newlines in 2/2 as noticed by Phillip and tweaked by\n>    Junio.\n>  * rebased on master (2953d95d40 (The eighth batch, 2024-03-15)), to avoid\n>    conflicts in 'Documentation/config/advice.txt' due to Kristoffer's merged\n>    series\n\nLooking good; will queue.  Thanks.\n"},{"id":"491442","messageId":"e040c631-42d9-4501-a7b8-046f8dac6309@gmail.com","threadId":"61038","inReplyTo":"pull.1682.v3.git.1710623790.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/2] Allow disabling advice shown after merge conflicts","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-25T10:48:12Z","receivedAt":"2024-03-25T10:48:15Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Philippe\n\nOn 16/03/2024 21:16, Philippe Blain via GitGitGadget wrote:\n> Changes since v2:\n> \n>   * expanded the commit messages to explain why the tests for 'git rebase' do\n>     not need to be adjusted\n>   * adjusted the wording of the new 'advice.mergeConflict' in the doc, as\n>     suggested by Kristoffer for uniformity with his series which is already\n>     merged to 'master' (b09a8839a4 (Merge branch\n>     'kh/branch-ref-syntax-advice', 2024-03-15)).\n>   * checked all new output manually and consequently adjusted the code in 1/2\n>     to avoid a lonely 'hint: ' line.\n>   * adjusted the addition in advice.h in 1/2 to put the new enum\n>     alphabetically, as noticed by Rubén.\n>   * added misssing newlines in 2/2 as noticed by Phillip and tweaked by\n>     Junio.\n>   * rebased on master (2953d95d40 (The eighth batch, 2024-03-15)), to avoid\n>     conflicts in 'Documentation/config/advice.txt' due to Kristoffer's merged >     series\n> [...] \n> Note that the code path where 'git rebase --apply' stops because of\n> conflicts is not covered by the tests but I tested it manually using this\n> diff:\n> \n> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n> index 47534f1062..34eac2e6f4 100755\n> --- a/t/t5520-pull.sh\n> +++ b/t/t5520-pull.sh\n> @@ -374,7 +374,7 @@ test_pull_autostash_fail ()\n>       echo conflicting >>seq.txt &&\n>       test_tick &&\n>       git commit -m \"Create conflict\" seq.txt &&\n> -\ttest_must_fail git pull --rebase . seq 2>err >out &&\n> +\ttest_must_fail git -c rebase.backend=apply pull --rebase . seq 2>err >out &&\n>       test_grep \"Resolve all conflicts manually\" err\n>   '\n\nThanks for being so thorough, this version looks good to me\n\nBest Wishes\n\nPhillip\n\n> \n> Philippe Blain (2):\n>    sequencer: allow disabling conflict advice\n>    builtin/am: allow disabling conflict advice\n> \n>   Documentation/config/advice.txt |  2 ++\n>   advice.c                        |  1 +\n>   advice.h                        |  1 +\n>   builtin/am.c                    | 14 +++++++++-----\n>   sequencer.c                     | 33 ++++++++++++++++++---------------\n>   t/t3501-revert-cherry-pick.sh   |  1 +\n>   t/t3507-cherry-pick-conflict.sh |  2 ++\n>   t/t4150-am.sh                   |  8 ++++----\n>   t/t4254-am-corrupt.sh           |  2 +-\n>   9 files changed, 39 insertions(+), 25 deletions(-)\n> \n> \n> base-commit: 2953d95d402b6bff1a59c4712f4d46f1b9ea137f\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1682%2Fphil-blain%2Fsequencer-conflict-advice-v3\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1682/phil-blain/sequencer-conflict-advice-v3\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1682\n> \n> Range-diff vs v2:\n> \n>   1:  a2ce6fd24c2 ! 1:  6005c1e9890 sequencer: allow disabling conflict advice\n>       @@ Commit message\n>            merge conflict through a new config 'advice.mergeConflict', which is\n>            named generically such that it can be used by other commands eventually.\n>        \n>       +    Remove that final '\\n' in the first hunk in sequencer.c to avoid an\n>       +    otherwise empty 'hint: ' line before the line 'hint: Disable this\n>       +    message with \"git config advice.mergeConflict false\"' which is\n>       +    automatically added by 'advise_if_enabled'.\n>       +\n>            Note that we use 'advise_if_enabled' for each message in the second hunk\n>            in sequencer.c, instead of using 'if (show_hints &&\n>            advice_enabled(...)', because the former instructs the user how to\n>       @@ Commit message\n>        \n>            Update the tests accordingly. Note that the body of the second test in\n>            t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must\n>       -    escape them in the added line.\n>       +    escape them in the added line. Note that t5520-pull.sh, which checks\n>       +    that we display the advice for 'git rebase' (via 'git pull --rebase')\n>       +    does not have to be updated because it only greps for a specific line in\n>       +    the advice message.\n>        \n>            Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n>        \n>         ## Documentation/config/advice.txt ##\n>        @@ Documentation/config/advice.txt: advice.*::\n>       - \t\tAdvice on how to set your identity configuration when\n>       - \t\tyour information is guessed from the system username and\n>       - \t\tdomain name.\n>       + \t\tShown when the user's information is guessed from the\n>       + \t\tsystem username and domain name, to tell the user how to\n>       + \t\tset their identity configuration.\n>        +\tmergeConflict::\n>       -+\t\tAdvice shown when various commands stop because of conflicts.\n>       ++\t\tShown when various commands stop because of conflicts.\n>         \tnestedTag::\n>       - \t\tAdvice shown if a user attempts to recursively tag a tag object.\n>       + \t\tShown when a user attempts to recursively tag a tag object.\n>         \tpushAlreadyExists::\n>        \n>         ## advice.c ##\n>       @@ advice.c: static struct {\n>        \n>         ## advice.h ##\n>        @@ advice.h: enum advice_type {\n>       + \tADVICE_GRAFT_FILE_DEPRECATED,\n>         \tADVICE_IGNORED_HOOK,\n>         \tADVICE_IMPLICIT_IDENTITY,\n>       - \tADVICE_NESTED_TAG,\n>        +\tADVICE_MERGE_CONFLICT,\n>       + \tADVICE_NESTED_TAG,\n>         \tADVICE_OBJECT_NAME_WARNING,\n>         \tADVICE_PUSH_ALREADY_EXISTS,\n>       - \tADVICE_PUSH_FETCH_FIRST,\n>        \n>         ## sequencer.c ##\n>        @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n>       @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,\n>         \n>         \tif (msg) {\n>        -\t\tadvise(\"%s\\n\", msg);\n>       -+\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\\n\", msg);\n>       ++\t\tadvise_if_enabled(ADVICE_MERGE_CONFLICT, \"%s\", msg);\n>         \t\t/*\n>         \t\t * A conflict has occurred but the porcelain\n>         \t\t * (typically rebase --interactive) wants to take care\n>   2:  3235542cc6f ! 2:  73d07c8b6a7 builtin/am: allow disabling conflict advice\n>       @@ Commit message\n>            on stderr instead of stdout. In t4150, redirect stdout to 'out' and\n>            stderr to 'err', since this is less confusing. In t4254, as we are\n>            testing a specific failure mode of 'git am', simply disable the advice.\n>       +    Note that we are not testing that this advice is shown in 'git rebase'\n>       +    for the apply backend since 2ac0d6273f (rebase: change the default\n>       +    backend from \"am\" to \"merge\", 2020-02-15).\n>        \n>       +    Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n>       +    Helped-by: Junio C Hamano <gitster@pobox.com>\n>            Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>\n>        \n>         ## builtin/am.c ##\n>       @@ builtin/am.c: static const char *msgnum(const struct am_state *state)\n>         \n>        -\t\tprintf_ln(_(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n>        -\t\tprintf_ln(_(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>       -+\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\"), cmdline);\n>       -+\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\"), cmdline);\n>       ++\t\tstrbuf_addf(&sb, _(\"When you have resolved this problem, run \\\"%s --continue\\\".\\n\"), cmdline);\n>       ++\t\tstrbuf_addf(&sb, _(\"If you prefer to skip this patch, run \\\"%s --skip\\\" instead.\\n\"), cmdline);\n>         \n>         \t\tif (advice_enabled(ADVICE_AM_WORK_DIR) &&\n>         \t\t    is_empty_or_missing_file(am_path(state, \"patch\")) &&\n>         \t\t    !repo_index_has_changes(the_repository, NULL, NULL))\n>        -\t\t\tprintf_ln(_(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n>       -+\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\"), cmdline);\n>       ++\t\t\tstrbuf_addf(&sb, _(\"To record the empty patch as an empty commit, run \\\"%s --allow-empty\\\".\\n\"), cmdline);\n>         \n>        -\t\tprintf_ln(_(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n>        +\t\tstrbuf_addf(&sb, _(\"To restore the original branch and stop patching, run \\\"%s --abort\\\".\"), cmdline);\n> \n\n"},{"id":"491465","messageId":"xmqqle66mep8.fsf@gitster.g","threadId":"61038","inReplyTo":"e040c631-42d9-4501-a7b8-046f8dac6309@gmail.com","subject":"Re: [PATCH v3 0/2] Allow disabling advice shown after merge conflicts","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-25T16:57:55Z","receivedAt":"2024-03-25T16:57:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> Hi Philippe\n>\n> On 16/03/2024 21:16, Philippe Blain via GitGitGadget wrote:\n>> Changes since v2:\n>>   * expanded the commit messages to explain why the tests for 'git\n>> rebase' do\n>>     not need to be adjusted\n>>   * adjusted the wording of the new 'advice.mergeConflict' in the doc, as\n>>     suggested by Kristoffer for uniformity with his series which is already\n>>     merged to 'master' (b09a8839a4 (Merge branch\n>>     'kh/branch-ref-syntax-advice', 2024-03-15)).\n>>   * checked all new output manually and consequently adjusted the code in 1/2\n>>     to avoid a lonely 'hint: ' line.\n>>   * adjusted the addition in advice.h in 1/2 to put the new enum\n>>     alphabetically, as noticed by Rubén.\n>>   * added misssing newlines in 2/2 as noticed by Phillip and tweaked by\n>>     Junio.\n>>   * rebased on master (2953d95d40 (The eighth batch, 2024-03-15)), to avoid\n>>     conflicts in 'Documentation/config/advice.txt' due to Kristoffer's merged >     series\n>> [...] Note that the code path where 'git rebase --apply' stops\n>> because of\n>> conflicts is not covered by the tests but I tested it manually using this\n>> diff:\n>> diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\n>> index 47534f1062..34eac2e6f4 100755\n>> --- a/t/t5520-pull.sh\n>> +++ b/t/t5520-pull.sh\n>> @@ -374,7 +374,7 @@ test_pull_autostash_fail ()\n>>       echo conflicting >>seq.txt &&\n>>       test_tick &&\n>>       git commit -m \"Create conflict\" seq.txt &&\n>> -\ttest_must_fail git pull --rebase . seq 2>err >out &&\n>> +\ttest_must_fail git -c rebase.backend=apply pull --rebase . seq 2>err >out &&\n>>       test_grep \"Resolve all conflicts manually\" err\n>>   '\n>\n> Thanks for being so thorough, this version looks good to me\n\nYup, these look good.  Let's mark the topic for 'next'.\n\nThanks, both.\n"}]}