{"thread":{"id":"66302","subject":"[PATCH v3] advice: use global config for default branch name","startedAt":"2026-09-09T19:58:19Z","lastAt":"2026-09-17T13:25:47Z","messageCount":30,"participants":["Vsevolod Myalitsin","Jeff King","Junio C Hamano","SZEDER Gábor"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"552373","messageId":"20270829004959.90983-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":null,"subject":"[PATCH v3] advice: use global config for default branch name","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2027-08-29T00:49:58Z","receivedAt":"2026-09-09T19:58:19Z","isPatch":true,"body":"Some advice messages suggest disabling the advice with\n\"git config set advice.<name> false\", even when the\ncorresponding configuration should be set at a different scope.\n\nAdd a scope hint to advice settings so that the suggested\ncommand uses the appropriate config scope.\n\nPass the advice setting itself to vadvise() instead of passing\nits fields separately. Use NULL for advise() calls that are not\nassociated with an advice setting.\n\nSigned-off-by: Vsevolod Myalitsin <ub4nal@mail.ru>\n---\n advice.c | 43 ++++++++++++++++++++++++++++++++-----------\n 1 file changed, 32 insertions(+), 11 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 63bf8b0c5f..80cc388215 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -40,10 +40,19 @@ enum advice_level {\n \tADVICE_LEVEL_ENABLED,\n };\n \n-static struct {\n+enum advice_scope {\n+\tADVICE_SCOPE_LOCAL = 0,\n+\tADVICE_SCOPE_GLOBAL,\n+\tADVICE_SCOPE_SYSTEM,\n+};\n+\n+struct advice_setting {\n \tconst char *key;\n+\tenum advice_scope scope_hint;\n \tenum advice_level level;\n-} advice_setting[] = {\n+};\n+\n+static struct advice_setting advice_setting[] = {\n \t[ADVICE_ADD_EMBEDDED_REPO]\t\t\t= { \"addEmbeddedRepo\" },\n \t[ADVICE_ADD_EMPTY_PATHSPEC]\t\t\t= { \"addEmptyPathspec\" },\n \t[ADVICE_ADD_IGNORED_FILE]\t\t\t= { \"addIgnoredFile\" },\n@@ -51,7 +60,7 @@ static struct {\n \t[ADVICE_AM_WORK_DIR] \t\t\t\t= { \"amWorkDir\" },\n \t[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] \t= { \"checkoutAmbiguousRemoteBranchName\" },\n \t[ADVICE_COMMIT_BEFORE_MERGE]\t\t\t= { \"commitBeforeMerge\" },\n-\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\" },\n+\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\", ADVICE_SCOPE_GLOBAL },\n \t[ADVICE_DETACHED_HEAD]\t\t\t\t= { \"detachedHead\" },\n \t[ADVICE_DIVERGING]\t\t\t\t= { \"diverging\" },\n \t[ADVICE_FETCH_SET_HEAD_WARN]\t\t\t= { \"fetchRemoteHEADWarn\" },\n@@ -96,18 +105,31 @@ static struct {\n \n static const char turn_off_instructions[] =\n N_(\"\\n\"\n-   \"Disable this message with \\\"git config set advice.%s false\\\"\");\n+   \"Disable this message with \\\"git config set%s advice.%s false\\\"\");\n \n-static void vadvise(const char *advice, int display_instructions,\n-\t\t    const char *key, va_list params)\n+static void vadvise(const char *advice,\n+\tconst struct advice_setting *setting, va_list params)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tconst char *cp, *np;\n \n \tstrbuf_vaddf(&buf, advice, params);\n \n-\tif (display_instructions)\n-\t\tstrbuf_addf(&buf, turn_off_instructions, key);\n+\tif (setting && setting->level == 0) {\n+\t\tconst char *scope = \"\";\n+\t\tswitch (setting->scope_hint) {\n+\t\t\tcase ADVICE_SCOPE_LOCAL:\n+\t\t\t\tbreak;\n+\t\t\tcase ADVICE_SCOPE_GLOBAL:\n+\t\t\t\tscope = \" --global\";\n+\t\t\t\tbreak;\n+\t\t\tcase ADVICE_SCOPE_SYSTEM:\n+\t\t\t\tscope = \" --system\";\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tstrbuf_addf(&buf, turn_off_instructions,\n+\t\t\t\tscope, setting->key);\n+\t}\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n@@ -126,7 +148,7 @@ void advise(const char *advice, ...)\n {\n \tva_list params;\n \tva_start(params, advice);\n-\tvadvise(advice, 0, \"\", params);\n+\tvadvise(advice, NULL, params);\n \tva_end(params);\n }\n \n@@ -155,8 +177,7 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...)\n \t\treturn;\n \n \tva_start(params, advice);\n-\tvadvise(advice, !advice_setting[type].level, advice_setting[type].key,\n-\t\tparams);\n+\tvadvise(advice, &advice_setting[type], params);\n \tva_end(params);\n }\n \n-- \n2.50.1\n\n"},{"id":"552377","messageId":"20260909202718.GA183838@coredump.intra.peff.net","threadId":"66302","inReplyTo":"20270829004959.90983-1-ub4nal@mail.ru","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-09T20:27:18Z","receivedAt":"2026-09-09T20:27:21Z","isPatch":true,"body":"On Sun, Aug 29, 2027 at 03:49:58AM +0300, Vsevolod Myalitsin wrote:\n\n> Add a scope hint to advice settings so that the suggested\n> command uses the appropriate config scope.\n> \n> Pass the advice setting itself to vadvise() instead of passing\n> its fields separately. Use NULL for advise() calls that are not\n> associated with an advice setting.\n\nThanks, this looks OK to me. A few small nits/observations:\n\n> @@ -96,18 +105,31 @@ static struct {\n>  \n>  static const char turn_off_instructions[] =\n>  N_(\"\\n\"\n> -   \"Disable this message with \\\"git config set advice.%s false\\\"\");\n> +   \"Disable this message with \\\"git config set%s advice.%s false\\\"\");\n\nTranslators will need to update their message translations, and I wonder\nif seeing this \"set%s\" in isolation might be confusing. Probably it\nshould be obvious that they should leave everything within the\ndouble-quotes alone. But the alternative is adding a comment with\n\"TRANSLATORS\" in it, I think.\n\nSee below, also.\n\n> -\tif (display_instructions)\n> -\t\tstrbuf_addf(&buf, turn_off_instructions, key);\n> +\tif (setting && setting->level == 0) {\n\nI left this comparison as something like \"!setting->level\" in my earlier\nsuggestion, which I think would be OK. But really it is an enum, and if\nwe are going to use \"==\" we should probably spell out the whole name\nrather than 0, like:\n\n  if (setting && setting->level == ADVICE_LEVEL_NONE)\n\n> +\t\tconst char *scope = \"\";\n> +\t\tswitch (setting->scope_hint) {\n> +\t\t\tcase ADVICE_SCOPE_LOCAL:\n> +\t\t\t\tbreak;\n> +\t\t\tcase ADVICE_SCOPE_GLOBAL:\n> +\t\t\t\tscope = \" --global\";\n> +\t\t\t\tbreak;\n> +\t\t\tcase ADVICE_SCOPE_SYSTEM:\n> +\t\t\t\tscope = \" --system\";\n> +\t\t\t\tbreak;\n> +\t\t}\n\nI had somehow hoped we could reuse the existing CONFIG_SCOPE enum\nwithout having to redeclare it ourselves. But there are a lot more\nscopes than these three! On the other hand, I think it would be possible\nto use config_scope_name() to convert them into options.\n\nThat makes the translation more lego-like, but maybe it would actually\nmake it easier to understand, because we could pull the whole command\nout into a single placeholder. Like:\n\ndiff --git a/advice.c b/advice.c\nindex cbb0f2f428..789f01c7e1 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -40,15 +40,9 @@ enum advice_level {\n \tADVICE_LEVEL_ENABLED,\n };\n \n-enum advice_scope {\n-\tADVICE_SCOPE_LOCAL = 0,\n-\tADVICE_SCOPE_GLOBAL,\n-\tADVICE_SCOPE_SYSTEM,\n-};\n-\n struct advice_setting {\n \tconst char *key;\n-\tenum advice_scope scope_hint;\n+\tenum config_scope scope_hint;\n \tenum advice_level level;\n };\n \n@@ -60,7 +54,7 @@ static struct advice_setting advice_setting[] = {\n \t[ADVICE_AM_WORK_DIR] \t\t\t\t= { \"amWorkDir\" },\n \t[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] \t= { \"checkoutAmbiguousRemoteBranchName\" },\n \t[ADVICE_COMMIT_BEFORE_MERGE]\t\t\t= { \"commitBeforeMerge\" },\n-\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\", ADVICE_SCOPE_GLOBAL },\n+\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\", CONFIG_SCOPE_GLOBAL },\n \t[ADVICE_DETACHED_HEAD]\t\t\t\t= { \"detachedHead\" },\n \t[ADVICE_DIVERGING]\t\t\t\t= { \"diverging\" },\n \t[ADVICE_FETCH_SET_HEAD_WARN]\t\t\t= { \"fetchRemoteHEADWarn\" },\n@@ -105,7 +99,7 @@ static struct advice_setting advice_setting[] = {\n \n static const char turn_off_instructions[] =\n N_(\"\\n\"\n-   \"Disable this message with \\\"git config set%s advice.%s false\\\"\");\n+   \"Disable this message with \\\"%s\");\n \n static void vadvise(const char *advice,\n \tconst struct advice_setting *setting, va_list params)\n@@ -116,19 +110,16 @@ static void vadvise(const char *advice,\n \tstrbuf_vaddf(&buf, advice, params);\n \n \tif (setting && setting->level == 0) {\n-\t\tconst char *scope = \"\";\n-\t\tswitch (setting->scope_hint) {\n-\t\t\tcase ADVICE_SCOPE_LOCAL:\n-\t\t\t\tbreak;\n-\t\t\tcase ADVICE_SCOPE_GLOBAL:\n-\t\t\t\tscope = \" --global\";\n-\t\t\t\tbreak;\n-\t\t\tcase ADVICE_SCOPE_SYSTEM:\n-\t\t\t\tscope = \" --system\";\n-\t\t\t\tbreak;\n-\t\t}\n-\t\tstrbuf_addf(&buf, turn_off_instructions,\n-\t\t\t\tscope, setting->key);\n+\t\tstruct strbuf cmd = STRBUF_INIT;\n+\n+\t\tstrbuf_addstr(&cmd, \"git config set\");\n+\t\tif (setting->scope_hint &&\n+\t\t    setting->scope_hint != CONFIG_SCOPE_LOCAL)\n+\t\t\tstrbuf_addf(&cmd, \" --%s\",\n+\t\t\t\t    config_scope_name(setting->scope_hint));\n+\t\tstrbuf_addf(&cmd, \"advice.%s false\", setting->key);\n+\t\tstrbuf_addf(&buf, turn_off_instructions, cmd.buf);\n+\t\tstrbuf_release(&cmd);\n \t}\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n\n\nHaving typed that, I'm not sure if it is more or less confusing. It does\navoid replicating the CONFIG_SCOPE enum. There is some lego-string\nconstruction, but it is all within the code and for the non-translated\ncommand. It would obviously be nonsense with CONFIG_SCOPE_FILE, but\nthere is no reason to think we'd ever pass that.\n\nSo I dunno. I could take or leave it as a further cleanup.\n\n-Peff\n"},{"id":"552378","messageId":"xmqqse3ip2s5.fsf@gitster.g","threadId":"66302","inReplyTo":"20270829004959.90983-1-ub4nal@mail.ru","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-09T20:50:50Z","receivedAt":"2026-09-09T20:50:55Z","isPatch":true,"body":"Vsevolod Myalitsin <ub4nal@mail.ru> writes:\n\n> Some advice messages suggest disabling the advice with\n> \"git config set advice.<name> false\", even when the\n> corresponding configuration should be set at a different scope.\n>\n> Add a scope hint to advice settings so that the suggested\n> command uses the appropriate config scope.\n>\n> Pass the advice setting itself to vadvise() instead of passing\n> its fields separately. Use NULL for advise() calls that are not\n> associated with an advice setting.\n\n\"\"\"Use this new mechanism to suggest setting advice.defaultBranchName \nin per-user configuration, not in per-repository configuration, as\nit is way too late once a repository is initialized.\"\"\" or something\nalong that line is missing here.\n\n> +enum advice_scope {\n> +\tADVICE_SCOPE_LOCAL = 0,\n> +\tADVICE_SCOPE_GLOBAL,\n> +\tADVICE_SCOPE_SYSTEM,\n> +};\n> +\n> +struct advice_setting {\n>  \tconst char *key;\n> +\tenum advice_scope scope_hint;\n>  \tenum advice_level level;\n> -} advice_setting[] = {\n> +};\n\nLooking good.\n\n> +static struct advice_setting advice_setting[] = {\n>  \t[ADVICE_ADD_EMBEDDED_REPO]\t\t\t= { \"addEmbeddedRepo\" },\n>  \t[ADVICE_ADD_EMPTY_PATHSPEC]\t\t\t= { \"addEmptyPathspec\" },\n>  \t[ADVICE_ADD_IGNORED_FILE]\t\t\t= { \"addIgnoredFile\" },\n> @@ -51,7 +60,7 @@ static struct {\n>  \t[ADVICE_AM_WORK_DIR] \t\t\t\t= { \"amWorkDir\" },\n>  \t[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] \t= { \"checkoutAmbiguousRemoteBranchName\" },\n>  \t[ADVICE_COMMIT_BEFORE_MERGE]\t\t\t= { \"commitBeforeMerge\" },\n> -\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\" },\n> +\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\", ADVICE_SCOPE_GLOBAL },\n>  \t[ADVICE_DETACHED_HEAD]\t\t\t\t= { \"detachedHead\" },\n>  \t[ADVICE_DIVERGING]\t\t\t\t= { \"diverging\" },\n>  \t[ADVICE_FETCH_SET_HEAD_WARN]\t\t\t= { \"fetchRemoteHEADWarn\" },\n> @@ -96,18 +105,31 @@ static struct {\n>  \n>  static const char turn_off_instructions[] =\n>  N_(\"\\n\"\n> -   \"Disable this message with \\\"git config set advice.%s false\\\"\");\n> +   \"Disable this message with \\\"git config set%s advice.%s false\\\"\");\n>  \n> -static void vadvise(const char *advice, int display_instructions,\n> -\t\t    const char *key, va_list params)\n> +static void vadvise(const char *advice,\n> +\tconst struct advice_setting *setting, va_list params)\n>  {\n>  \tstruct strbuf buf = STRBUF_INIT;\n>  \tconst char *cp, *np;\n>  \n>  \tstrbuf_vaddf(&buf, advice, params);\n>  \n> -\tif (display_instructions)\n> -\t\tstrbuf_addf(&buf, turn_off_instructions, key);\n> +\tif (setting && setting->level == 0) {\n> +\t\tconst char *scope = \"\";\n> +\t\tswitch (setting->scope_hint) {\n> +\t\t\tcase ADVICE_SCOPE_LOCAL:\n> +\t\t\t\tbreak;\n> +\t\t\tcase ADVICE_SCOPE_GLOBAL:\n> +\t\t\t\tscope = \" --global\";\n> +\t\t\t\tbreak;\n> +\t\t\tcase ADVICE_SCOPE_SYSTEM:\n> +\t\t\t\tscope = \" --system\";\n> +\t\t\t\tbreak;\n> +\t\t}\n\nStyle.  In our codebase, switch and case are indented to the same\ntabstop.\n\n> +\t\tstrbuf_addf(&buf, turn_off_instructions,\n> +\t\t\t\tscope, setting->key);\n> +\t}\n>  \n>  \tfor (cp = buf.buf; *cp; cp = np) {\n>  \t\tnp = strchrnul(cp, '\\n');\n> @@ -126,7 +148,7 @@ void advise(const char *advice, ...)\n>  {\n>  \tva_list params;\n>  \tva_start(params, advice);\n> -\tvadvise(advice, 0, \"\", params);\n> +\tvadvise(advice, NULL, params);\n>  \tva_end(params);\n>  }\n>  \n> @@ -155,8 +177,7 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...)\n>  \t\treturn;\n>  \n>  \tva_start(params, advice);\n> -\tvadvise(advice, !advice_setting[type].level, advice_setting[type].key,\n> -\t\tparams);\n> +\tvadvise(advice, &advice_setting[type], params);\n>  \tva_end(params);\n>  }\n\nThe change to narrow the interface into vadvise() needs to be\ndescribed in the proposed log message.\n\nIdeally, this would be a three-patch series.  API change to\nvadvise() would come first, and then the introduction of advice\nscope mechanism, and finally making defaultBranchName a global\nscope variable.\n\nOther than that, the end shape looks good to me.\n\nThanks.\n"},{"id":"552382","messageId":"xmqqecf2p1dd.fsf@gitster.g","threadId":"66302","inReplyTo":"20260909202718.GA183838@coredump.intra.peff.net","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-09T21:21:18Z","receivedAt":"2026-09-09T21:21:21Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> I had somehow hoped we could reuse the existing CONFIG_SCOPE enum\n> without having to redeclare it ourselves. But there are a lot more\n> scopes than these three! On the other hand, I think it would be possible\n> to use config_scope_name() to convert them into options.\n\nI had the same thought, and do not have strong opinion myself either\nway.\n\nFor everything else you suggested in your review, I think we would\nwant a hopefully small and final reroll.\n\nThanks.\n\n"},{"id":"552383","messageId":"20260909212214.94151-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260909202718.GA183838@coredump.intra.peff.net","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-09T21:22:13Z","receivedAt":"2026-09-09T21:23:46Z","isPatch":true,"body":"Hi Peff,\n\n> Translators will need to update their message translations, and I wonder\n> if seeing this \"set%s\" in isolation might be confusing.\n\nI agree that using a single placeholder for the whole command is clearer for translators. I'll use this approach.\n\n> But really it is an enum, and if we are going to use \"==\" we should\n> probably spell out the whole name rather than 0, like:\n\nif (setting && setting->level == ADVICE_LEVEL_NONE)\n\nI simply forgot to include this change in the patch. I'll change it to use ADVICE_LEVEL_NONE.\n\n> I had somehow hoped we could reuse the existing CONFIG_SCOPE enum\n> without having to redeclare it ourselves.\n\nOne concern about reusing enum config_scope: since CONFIG_SCOPE_UNKNOWN is 0, all existing advice_setting entries without an explicitly specified scope_hint would default to CONFIG_SCOPE_UNKNOWN rather than CONFIG_SCOPE_LOCAL.\n\nI believe this is incorrect, since the existing behavior is local scope by default. However, if you consider CONFIG_SCOPE_UNKNOWN appropriate here and it satisfies the intended requirements, I have no objection to using the existing enum.\n\nThanks,\nVsevolod\n"},{"id":"552384","messageId":"20260909213034.94554-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"xmqqse3ip2s5.fsf@gitster.g","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-09T21:30:34Z","receivedAt":"2026-09-09T21:32:00Z","isPatch":true,"body":"Hi Junio,\n\nThanks for the review.\n\n> \"\"\"Use this new mechanism to suggest setting advice.defaultBranchName\n> in per-user configuration, not in per-repository configuration, as\n> it is way too late once a repository is initialized.\"\"\" or something\n> along that line is missing here.\n\nAgreed. I'll add this motivation to the commit message.\n\n> The change to narrow the interface into vadvise() needs to be\n> described in the proposed log message.\n\nI'll describe this change in the appropriate commit message.\n\n> Ideally, this would be a three-patch series. API change to\n> vadvise() would come first, and then the introduction of advice\n> scope mechanism, and finally making defaultBranchName a global\n> scope variable.\n\nAgreed. I'll split the changes into three patches in this order.\n\nI have one question about how the series should be organized. Since the\nthree patches will have different purposes, should each patch have its\nown subject and commit message describing the changes introduced by that\npatch? Or should they share a common subject/theme, with the individual\nchanges described in the respective commit messages?\n\n> Style. In our codebase, switch and case are indented to the same\ntabstop.\n\nI'll fix the indentation.\n\n> Other than that, the end shape looks good to me.\n\nThanks!\n\nVsevolod\n"},{"id":"552386","messageId":"xmqqzexqnjkb.fsf@gitster.g","threadId":"66302","inReplyTo":"20260909213034.94554-1-ub4nal@mail.ru","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-09T22:31:16Z","receivedAt":"2026-09-09T22:31:20Z","isPatch":true,"body":"Vsevolod Myalitsin <ub4nal@mail.ru> writes:\n\n> I have one question about how the series should be organized. Since the\n> three patches will have different purposes, should each patch have its\n> own subject and commit message describing the changes introduced by that\n> patch? Or should they share a common subject/theme, with the individual\n> changes described in the respective commit messages?\n\nSorry, but I do not quite understand what is being asked.\n\nFor example, if you had a 4-patch series like\n\n  https://lore.kernel.org/git/20260909-758-introduce-hook-v9-0-3043d417e0ee@gmail.com/\n\nhow would you characterize each patch in it?  These 4 patches share\nthe same goal in bigger picture (after all that is why they are in a\nsingle series) yet each step has its own agenda (each of them can be\nexplained separately as a logical unit, and that is why you are\nmaking them separate patches to ease reading and understanding).\nEach patch comes with its own title and explian the background (the\nobservation of the status quo) and what it wants to solve and how.\n\nYour three-patch series would be quite similar.  If you want to\ndescribe the motivation and overall structure of the solution, a\ncover letter would make a good place to do so, and then each patch\ndoes so in a smaller scale in its proposed log message.\nThe contents of each message may begin like so:\n\n [0/3] defaultBranchName advice is useless\n\n It does not make much sense to set the advice.defaultBranchName\n configuration variable in a per-repository configuration file, as\n once a repository is initialized, the advice will never fire.  We\n need to mechanism to mark such advice messages so that the message\n to tell what advice.* variable to tweak can suggest doing so in a\n per-user or even per-system configuration files.\n\n This series consists of three steps, ...\n\n [1/3] advice: pass the entire advice_setting to vadvise()\n\n The internal function vadvice() takes values taken from members of\n an advice_settings struct individually, which is cumbersome to\n extend.  Instead, pass the advice_settings instance so that the\n function can be extended by adding new members ot advnce_settings\n struct, without changing the signature of vadvise() function.\n\n [2/3] advice: introduce advice scoping mechanism\n\n The hint on how to squelch advice message told users to set\n advice.X configuration variable to false to squelch it, but for\n some variables, setting it globally in per-user configuration file\n is more appropriate.  Add a new member to advice_settings struct to\n indicate which config scope the variable should be set, and adjust\n the message.\n\n...\n\nBy the way, when you prepare a v4, make sure that the cover letter\nof the 3-patch series is a reply to your v3 patch, and each patch in\nthe series is a reply to the cover letter of v4.  That would give us\na nice threading on the mailing list archive and help automation.\n\nThanks.\n"},{"id":"552387","messageId":"20260909224603.GA195381@coredump.intra.peff.net","threadId":"66302","inReplyTo":"20260909212214.94151-1-ub4nal@mail.ru","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-09T22:46:03Z","receivedAt":"2026-09-09T22:46:10Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 12:22:13AM +0300, Vsevolod Myalitsin wrote:\n\n> > I had somehow hoped we could reuse the existing CONFIG_SCOPE enum\n> > without having to redeclare it ourselves.\n> \n> One concern about reusing enum config_scope: since\n> CONFIG_SCOPE_UNKNOWN is 0, all existing advice_setting entries without\n> an explicitly specified scope_hint would default to\n> CONFIG_SCOPE_UNKNOWN rather than CONFIG_SCOPE_LOCAL.\n> \n> I believe this is incorrect, since the existing behavior is local\n> scope by default. However, if you consider CONFIG_SCOPE_UNKNOWN\n> appropriate here and it satisfies the intended requirements, I have no\n> objection to using the existing enum.\n\nAny config can work at any scope. These are really just recommendations\non where the user might want to write a value. So I think it would be\nfine to treat UNKNOWN as \"just suggest the default location for\nwriting\", as we do now.\n\nTBH, I am not really sure what the criteria are for suggesting one\nadvice option as --global or not. I'd think most of them are about\nsquelching advice that the user already knows about, and thus they would\ngo into --global. I didn't really follow the earlier discussion that led\nup to this patch, though.\n\n-Peff\n"},{"id":"552396","messageId":"20260910044307.95376-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260909224603.GA195381@coredump.intra.peff.net","subject":"Re: [PATCH v3] advice: use global config for default branch name","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T04:43:07Z","receivedAt":"2026-09-10T05:05:53Z","isPatch":true,"body":"> Any config can work at any scope. These are really just recommendations on where the user might want to write a value.\n\nLooking at it from that perspective, this seems obvious to me now. I'll reuse the existing CONFIG_SCOPE enum and treat CONFIG_SCOPE_UNKNOWN as the default location.\n\n> TBH, I am not really sure what the criteria are for suggesting one advice option as --global or not.\n\nThe motivation for this patch was that \"advice.defaultBranchName\" currently suggests:\n\n\"git config set advice.defaultBranchName false\"\n\nWithout an explicit scope, this writes to the local \".git/config\". After the repository has been initialized, that particular scenario won't occur again in that repository. However, when the user initializes a new repository, the advice will appear again, which may make them wonder why they ran the command in the first place.\n\nTherefore, I think \"defaultBranchName\" should suggest using the global scope.\n\n> I'd think most of them are about squelching advice that the user already knows about, and thus they would go into --global.\n\nI agree that this may apply to many of the advice messages. For this patch, though, I'm specifically addressing \"defaultBranchName\", where the global scope seems appropriate for the reason above.\n\n> I didn't really follow the earlier discussion that led up to this patch, though.\n\nThe original motivation was specifically the behavior of \"defaultBranchName\" after initializing a new repository, which is why I considered a global scope recommendation here.\n\nVsevolod\n"},{"id":"552423","messageId":"20260910085353.109373-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20270829004959.90983-1-ub4nal@mail.ru","subject":"[PATCH v4 0/3] defaultBranchName advice is useless","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T08:53:50Z","receivedAt":"2026-09-10T08:54:12Z","isPatch":true,"body":"The advice for setting the default branch name currently suggests\ndisabling it with the following command:\n\ngit config set advice.defaultBranchName false\n\nWithout an explicit scope, this command writes the setting to the\ncurrent repository's configuration. This is not particularly useful\nhere, since the advice is shown while initializing a repository, and\nthe initialization scenario does not repeat for that repository.\nAs a result, the setting only affects the repository where the advice\nhas already been shown, while the advice appears again when a new\nrepository is initialized.\n\nSuggest using the global configuration scope instead, so that disabling\nthe advice applies to future repositories as well.\n\nThis series prepares the advice infrastructure for specifying a\nconfiguration scope and then uses it for defaultBranchName advice.\n\nThe series is structured as follows:\n\n1. Pass the entire advice_setting structure to vadvise().\n2. Introduce a configuration scope hint for advice settings.\n3. Suggest the global configuration scope for defaultBranchName advice.\n\nVsevolod Myalitsin (3):\n  advice: pass the entire advice_setting to vadvise()\n  advice: introduce advice scoping mechanism\n  advice: use global config for default branch name\n\n advice.c | 45 ++++++++++++++++++++++++++++++++++-----------\n 1 file changed, 34 insertions(+), 11 deletions(-)\n\n-- \n2.50.1\n\n"},{"id":"552422","messageId":"20260910085353.109373-3-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260910085353.109373-1-ub4nal@mail.ru","subject":"[PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T08:53:52Z","receivedAt":"2026-09-10T08:54:13Z","isPatch":true,"body":"The advice settings currently do not distinguish between configuration\nscopes. Add a scope hint to advice_setting so that an advice can\nrecommend a specific configuration scope when disabling it.\n\nUse the existing enum config_scope to represent the scope, with\nCONFIG_SCOPE_UNKNOWN indicating that the default configuration scope\nshould be used.\n\nSigned-off-by: Vsevolod Myalitsin <ub4nal@mail.ru>\n---\n advice.c | 25 +++++++++++++++++++++++--\n 1 file changed, 23 insertions(+), 2 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex b556c8b38e..12a68ea716 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -42,6 +42,7 @@ enum advice_level {\n \n struct advice_setting {\n \tconst char *key;\n+\tenum config_scope scope_hint;\n \tenum advice_level level;\n };\n \n@@ -96,9 +97,16 @@ static struct advice_setting advice_setting[] = {\n \t[ADVICE_WORKTREE_ADD_ORPHAN]\t\t\t= { \"worktreeAddOrphan\" },\n };\n \n+/*\n+ * TRANSLATORS: This is a command line that the user should run.\n+ *              Do not translate the part inside double quotes.\n+ *              The first %s is the config scope (e.g. \" --global\"),\n+ *              the second %s is the advice key (e.g. \"defaultBranchName\").\n+ */\n+\n static const char turn_off_instructions[] =\n N_(\"\\n\"\n-   \"Disable this message with \\\"git config set advice.%s false\\\"\");\n+   \"Disable this message with \\\"git config set%s advice.%s false\\\"\");\n \n static void vadvise(const char *advice,\n \tconst struct advice_setting *setting, va_list params)\n@@ -109,8 +117,21 @@ static void vadvise(const char *advice,\n \tstrbuf_vaddf(&buf, advice, params);\n \n \tif (setting && setting->level == ADVICE_LEVEL_NONE) {\n+\t\tconst char *scope = \"\";\n+\t\tswitch (setting->scope_hint) {\n+\t\tcase CONFIG_SCOPE_LOCAL:\n+\t\tcase CONFIG_SCOPE_UNKNOWN:\n+\t\t\tbreak;\n+\t\tcase CONFIG_SCOPE_GLOBAL:\n+\t\t\tscope = \" --global\";\n+\t\t\tbreak;\n+\t\tcase CONFIG_SCOPE_SYSTEM:\n+\t\t\tscope = \" --system\";\n+\t\t\tbreak;\n+\t\t}\n \t\tstrbuf_addf(&buf, turn_off_instructions,\n-\t\t\t\t\tsetting->key);\n+\t\t\t\tscope, setting->key);\n+\t}\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n-- \n2.50.1\n\n"},{"id":"552424","messageId":"20260910085353.109373-4-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260910085353.109373-1-ub4nal@mail.ru","subject":"[PATCH v4 3/3] advice: use global config for default branch name","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T08:53:53Z","receivedAt":"2026-09-10T08:54:14Z","isPatch":true,"body":"The advice for setting the default branch name currently suggests\ndisabling it with a local configuration value.\n\nThis makes the advice appear again when a new repository is initialized.\nSuggest using the global configuration scope instead, so that disabling\nthe advice applies to future repositories as well.\n\nSigned-off-by: Vsevolod Myalitsin <ub4nal@mail.ru>\n---\n advice.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/advice.c b/advice.c\nindex 12a68ea716..6964a6e2ba 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -54,7 +54,7 @@ static struct advice_setting advice_setting[] = {\n \t[ADVICE_AM_WORK_DIR] \t\t\t\t= { \"amWorkDir\" },\n \t[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] \t= { \"checkoutAmbiguousRemoteBranchName\" },\n \t[ADVICE_COMMIT_BEFORE_MERGE]\t\t\t= { \"commitBeforeMerge\" },\n-\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\" },\n+\t[ADVICE_DEFAULT_BRANCH_NAME]\t\t\t= { \"defaultBranchName\", CONFIG_SCOPE_GLOBAL },\n \t[ADVICE_DETACHED_HEAD]\t\t\t\t= { \"detachedHead\" },\n \t[ADVICE_DIVERGING]\t\t\t\t= { \"diverging\" },\n \t[ADVICE_FETCH_SET_HEAD_WARN]\t\t\t= { \"fetchRemoteHEADWarn\" },\n-- \n2.50.1\n\n"},{"id":"552425","messageId":"20260910085353.109373-2-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260910085353.109373-1-ub4nal@mail.ru","subject":"[PATCH v4 1/3] advice: pass the entire advice_setting to vadvise()","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T08:53:51Z","receivedAt":"2026-09-10T09:11:47Z","isPatch":true,"body":"Currently, vadvise() takes the advice level and configuration key as\nseparate arguments. Pass the entire advice_setting structure instead.\n\nThis keeps the advice configuration together and makes it possible for\nvadvise() to access additional properties of an advice setting without\nchanging its interface again.\n\nSigned-off-by: Vsevolod Myalitsin <ub4nal@mail.ru>\n---\n advice.c | 20 +++++++++++---------\n 1 file changed, 11 insertions(+), 9 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 63bf8b0c5f..b556c8b38e 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -40,10 +40,12 @@ enum advice_level {\n \tADVICE_LEVEL_ENABLED,\n };\n \n-static struct {\n+struct advice_setting {\n \tconst char *key;\n \tenum advice_level level;\n-} advice_setting[] = {\n+};\n+\n+static struct advice_setting advice_setting[] = {\n \t[ADVICE_ADD_EMBEDDED_REPO]\t\t\t= { \"addEmbeddedRepo\" },\n \t[ADVICE_ADD_EMPTY_PATHSPEC]\t\t\t= { \"addEmptyPathspec\" },\n \t[ADVICE_ADD_IGNORED_FILE]\t\t\t= { \"addIgnoredFile\" },\n@@ -98,16 +100,17 @@ static const char turn_off_instructions[] =\n N_(\"\\n\"\n    \"Disable this message with \\\"git config set advice.%s false\\\"\");\n \n-static void vadvise(const char *advice, int display_instructions,\n-\t\t    const char *key, va_list params)\n+static void vadvise(const char *advice,\n+\tconst struct advice_setting *setting, va_list params)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tconst char *cp, *np;\n \n \tstrbuf_vaddf(&buf, advice, params);\n \n-\tif (display_instructions)\n-\t\tstrbuf_addf(&buf, turn_off_instructions, key);\n+\tif (setting && setting->level == ADVICE_LEVEL_NONE) {\n+\t\tstrbuf_addf(&buf, turn_off_instructions,\n+\t\t\t\t\tsetting->key);\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n@@ -126,7 +129,7 @@ void advise(const char *advice, ...)\n {\n \tva_list params;\n \tva_start(params, advice);\n-\tvadvise(advice, 0, \"\", params);\n+\tvadvise(advice, NULL, params);\n \tva_end(params);\n }\n \n@@ -155,8 +158,7 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...)\n \t\treturn;\n \n \tva_start(params, advice);\n-\tvadvise(advice, !advice_setting[type].level, advice_setting[type].key,\n-\t\tparams);\n+\tvadvise(advice, &advice_setting[type], params);\n \tva_end(params);\n }\n \n-- \n2.50.1\n\n"},{"id":"552460","messageId":"xmqqzexpf78k.fsf@gitster.g","threadId":"66302","inReplyTo":"20260910085353.109373-3-ub4nal@mail.ru","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-10T15:36:59Z","receivedAt":"2026-09-10T15:37:02Z","isPatch":true,"body":"Vsevolod Myalitsin <ub4nal@mail.ru> writes:\n\n> @@ -109,8 +117,21 @@ static void vadvise(const char *advice,\n>  \tstrbuf_vaddf(&buf, advice, params);\n>  \n>  \tif (setting && setting->level == ADVICE_LEVEL_NONE) {\n> +\t\tconst char *scope = \"\";\n> +\t\tswitch (setting->scope_hint) {\n> +\t\tcase CONFIG_SCOPE_LOCAL:\n> +\t\tcase CONFIG_SCOPE_UNKNOWN:\n> +\t\t\tbreak;\n> +\t\tcase CONFIG_SCOPE_GLOBAL:\n> +\t\t\tscope = \" --global\";\n> +\t\t\tbreak;\n> +\t\tcase CONFIG_SCOPE_SYSTEM:\n> +\t\t\tscope = \" --system\";\n> +\t\t\tbreak;\n> +\t\t}\n\nmake DEVELOPER=YesPlease would die due to\n\nadvice.c: In function 'vadvise':\nadvice.c:123:17: error: enumeration value 'CONFIG_SCOPE_WORKTREE' not handled in switch [-Werror=switch]\n  123 |                 switch (setting->scope_hint) {\n      |                 ^~~~~~\nadvice.c:123:17: error: enumeration value 'CONFIG_SCOPE_COMMAND' not handled in switch [-Werror=switch]\nadvice.c:123:17: error: enumeration value 'CONFIG_SCOPE_SUBMODULE' not handled in switch [-Werror=switch]\n\nWe probably should have\n\n\t\tdefault:\n\t\t\tBUG(\"advice settings at wrong config scope\");\n\nor something there.\n\n>  \t\tstrbuf_addf(&buf, turn_off_instructions,\n> -\t\t\t\t\tsetting->key);\n> +\t\t\t\tscope, setting->key);\n> +\t}\n>  \n>  \tfor (cp = buf.buf; *cp; cp = np) {\n>  \t\tnp = strchrnul(cp, '\\n');\n"},{"id":"552461","messageId":"20260910155247.GA251185@coredump.intra.peff.net","threadId":"66302","inReplyTo":"xmqqzexpf78k.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-10T15:52:47Z","receivedAt":"2026-09-10T15:52:49Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 08:36:59AM -0700, Junio C Hamano wrote:\n\n> > @@ -109,8 +117,21 @@ static void vadvise(const char *advice,\n> >  \tstrbuf_vaddf(&buf, advice, params);\n> >  \n> >  \tif (setting && setting->level == ADVICE_LEVEL_NONE) {\n> > +\t\tconst char *scope = \"\";\n> > +\t\tswitch (setting->scope_hint) {\n> > +\t\tcase CONFIG_SCOPE_LOCAL:\n> > +\t\tcase CONFIG_SCOPE_UNKNOWN:\n> > +\t\t\tbreak;\n> > +\t\tcase CONFIG_SCOPE_GLOBAL:\n> > +\t\t\tscope = \" --global\";\n> > +\t\t\tbreak;\n> > +\t\tcase CONFIG_SCOPE_SYSTEM:\n> > +\t\t\tscope = \" --system\";\n> > +\t\t\tbreak;\n> > +\t\t}\n> \n> make DEVELOPER=YesPlease would die due to\n> \n> advice.c: In function 'vadvise':\n> advice.c:123:17: error: enumeration value 'CONFIG_SCOPE_WORKTREE' not handled in switch [-Werror=switch]\n>   123 |                 switch (setting->scope_hint) {\n>       |                 ^~~~~~\n> advice.c:123:17: error: enumeration value 'CONFIG_SCOPE_COMMAND' not handled in switch [-Werror=switch]\n> advice.c:123:17: error: enumeration value 'CONFIG_SCOPE_SUBMODULE' not handled in switch [-Werror=switch]\n> \n> We probably should have\n> \n> \t\tdefault:\n> \t\t\tBUG(\"advice settings at wrong config scope\");\n> \n> or something there.\n\nIt is funny that we would handle LOCAL here (which we do not expect\nanybody to pass) but would BUG() on other stuff like WORKTREE (which we\nalso would not expect).\n\nSo if we are going to do a switch statement, then I'd expect:\n\n  switch (setting->scope_hint) {\n  case CONFIG_SCOPE_GLOBAL:\n\tscope = \" --global\";\n\tbreak;\n  case CONFIG_SCOPE_SYSTEM:\n\tscope = \" --system\";\n\tbreak;\n  default:\n\t/*\n\t * Scope is local or otherwise unsupported; just recommend\n\t * the usual unadorned config command.\n         */\n\tbreak;\n  }\n\nI guess maybe that would surprise somebody who tried to add\nCONFIG_SCOPE_WORKTREE support, and they'd rather see a BUG(). I dunno.\n\nI was hoping we could avoid enumerating things at all here, but using\nconfig_scope_name() did involve a bit more string construction (and a\nhidden assumption that each scope name has a matching \"--foo\" option).\n\nI'm really not sure why anybody would use those other flags, though (or\neven --system, for that matter). After reading the thread again, I get\nwhy we want \"--global\" for advice that only affects new repository\ncreation (like defaultBranchName), since otherwise it could never have\nany effect. But why would you ever want --system?\n\nI feel like we are maybe leading poor Vsevolod in circles, though. At\nsome point there are diminishing returns for polishing this.\n\n-Peff\n"},{"id":"552476","messageId":"aqLsMDcvqgRZ8MVO@szeder.dev","threadId":"66302","inReplyTo":"20260910085353.109373-2-ub4nal@mail.ru","subject":"Re: [PATCH v4 1/3] advice: pass the entire advice_setting to vadvise()","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2026-09-10T17:43:12Z","receivedAt":"2026-09-10T17:43:16Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 11:53:51AM +0300, Vsevolod Myalitsin wrote:\n> @@ -98,16 +100,17 @@ static const char turn_off_instructions[] =\n>  N_(\"\\n\"\n>     \"Disable this message with \\\"git config set advice.%s false\\\"\");\n>  \n> -static void vadvise(const char *advice, int display_instructions,\n> -\t\t    const char *key, va_list params)\n> +static void vadvise(const char *advice,\n> +\tconst struct advice_setting *setting, va_list params)\n>  {\n>  \tstruct strbuf buf = STRBUF_INIT;\n>  \tconst char *cp, *np;\n>  \n>  \tstrbuf_vaddf(&buf, advice, params);\n>  \n> -\tif (display_instructions)\n> -\t\tstrbuf_addf(&buf, turn_off_instructions, key);\n> +\tif (setting && setting->level == ADVICE_LEVEL_NONE) {\n\nThere is an opening brace at the end of this line ...\n\n> +\t\tstrbuf_addf(&buf, turn_off_instructions,\n> +\t\t\t\t\tsetting->key);\n\n... but there is no corresponding closing brace here, leading to\ncompilation errors.\n\nPlease make sure that each and every commit you submit can be built.\n\n>  \n>  \tfor (cp = buf.buf; *cp; cp = np) {\n>  \t\tnp = strchrnul(cp, '\\n');\n"},{"id":"552478","messageId":"20260910175416.115280-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"20260910155247.GA251185@coredump.intra.peff.net","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-10T17:54:15Z","receivedAt":"2026-09-10T17:54:25Z","isPatch":true,"body":"Hi, Jeff!\n\n> I'm really not sure why anybody would use those other flags, though (or\n> even --system, for that matter). After reading the thread again, I get\n> why we want \"--global\" for advice that only affects new repository\n> creation (like defaultBranchName), since otherwise it could never have\n> any effect. But why would you ever want --system?\n\nI initially looked at Junio's suggestion and, based on his experience, didn't argue with it, and then I didn't come back to that message. I think the patch should contain not + enum config_scope scope_hint; but + bool is_global_hint;, since I myself can't find any scenarios where advice should be disabled at the system level.\n"},{"id":"552480","messageId":"xmqqpkyldke1.fsf@gitster.g","threadId":"66302","inReplyTo":"20260910155247.GA251185@coredump.intra.peff.net","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-10T18:35:50Z","receivedAt":"2026-09-10T18:35:53Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> I'm really not sure why anybody would use those other flags, though (or\n> even --system, for that matter). After reading the thread again, I get\n> why we want \"--global\" for advice that only affects new repository\n> creation (like defaultBranchName), since otherwise it could never have\n> any effect. But why would you ever want --system?\n\nNo particular concrete expected use case in mind.  But I figured\nthat it would not be too much additional effort to allow other\nscopes once we need to add support to allow \"--global\" to be added\nto the message.  I didn't think of \"--worktree\", but now you have\nmentioned it, I tend to think it is more plausible to have real use\ncase than \"--system\" (which users often do not even have power to\nset).\n\nThe primary reason why I didn't think of \"--worktree\" is because\noutput of \"git config --help\" has room for improvements.  This is a\ntangent, but one of its SYNOPSIS item reads like this:\n\n\tgit config set [<file-option>] [--type=<type>] [--all] \\\n\t\t[--value=<pattern>] [--fixed-value] <name> <value>\n\nAnd nowhere in the body of the documentation there is any\ndescription on what <file-option> is.  There is this sentence\n\n    ... and options --system, --global, --local, --worktree and\n    --file <filename> can be used to tell the command to read from\n    only that location.\n\nin one paragraph that gives enough hints that these five options are\nrelated to each other and give the closest thing as the definition\nof <file-option>, but I wouldn't call it a very good form of\ndocumentation.\n\nThere is a section called FILES, at the end of which has\n\n       You can limit which configuration sources are read from or\n       written to by specifying the path of a file with the --file\n       option, or by specifying a configuration scope with --system,\n       --global, --local, or --worktree. For more, see the section\n       called “OPTIONS” above.\n\nbut it is not explicit that the section is talking about\n<file-option>, either.\n\n--- >8 ---\nSubject: [PATCH] doc: clarify <file-option> in \"git config --help\"\n\nThe SYNOPSIS section of \"git config --help\" refers to <file-option>\nwithout explaining what they really mean.\n\nI *think* they meant to refer to the mechanism to limit the file(s)\nread from or written to by giving the scope options or the '--file\n<filename>' option.  Spell it out early in the description.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * The SYNOPSIS section also refers to <display-option> for many\n   operations; I have no idea what it means.  I left a needswork\n   comment there.  We should either clarify it in a similar way, or\n   remove it if it does not refer to anything.\n\n Documentation/git-config.adoc | 6 ++++++\n 1 file changed, 6 insertions(+)\n\ndiff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc\nindex 57af010ade..3673226505 100644\n--- a/Documentation/git-config.adoc\n+++ b/Documentation/git-config.adoc\n@@ -39,6 +39,12 @@ outgoing values are canonicalize-able under the given <type>.  If no\n `--type=<type>` is given, no canonicalization will be performed. Callers may\n unset an existing `--type` specifier with `--no-type`.\n \n+The `<file-option>` in the SYNOPSIS refers to options that limit the\n+read/write operations to a specific scope (see <<SCOPES>>) or a single\n+file (see <<FILES>>).\n+\n+// NEEDSWORK: What is the `<display-option>` meant to refer to?\n+\n When reading, the values are read from the system, global and\n repository local configuration files by default, and options\n `--system`, `--global`, `--local`, `--worktree` and\n-- \n2.56.0-rc0-135-g9520983108\n\n"},{"id":"552482","messageId":"20260910190345.GA903701@coredump.intra.peff.net","threadId":"66302","inReplyTo":"xmqqpkyldke1.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-10T19:03:45Z","receivedAt":"2026-09-10T19:03:47Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 11:35:50AM -0700, Junio C Hamano wrote:\n\n> The primary reason why I didn't think of \"--worktree\" is because\n> output of \"git config --help\" has room for improvements.  This is a\n> tangent, but one of its SYNOPSIS item reads like this:\n> \n> \tgit config set [<file-option>] [--type=<type>] [--all] \\\n> \t\t[--value=<pattern>] [--fixed-value] <name> <value>\n\nIf it makes you feel any better, I did not even know --worktree existed\nuntil today. ;) I only discovered it when looking at the possible values\nreturned by config_scope_name().\n\nI still have trouble imagining why a particular piece of advice would\nmake sense only in --worktree mode. The only concrete case I've seen for\nany advice scoping is that clone/init advice config does not make sense\nin repo config. And --global is the sensible solution to that (--system\nworks, too, but it is not a very helpful recommendation).\n\nI kind of wonder if _all_ advice should just say \"--global\". I cannot\nthink of an advice flag that is really repo specific. They are about\nsilencing extra help because the _user_ understands the situation and\nwants Git to be less chatty.\n\n> --- >8 ---\n> Subject: [PATCH] doc: clarify <file-option> in \"git config --help\"\n> \n> The SYNOPSIS section of \"git config --help\" refers to <file-option>\n> without explaining what they really mean.\n> \n> I *think* they meant to refer to the mechanism to limit the file(s)\n> read from or written to by giving the scope options or the '--file\n> <filename>' option.  Spell it out early in the description.\n\nI agree that we should use the term <file-option> to refer to it. I\nthink the paragraphs just below what you touched try to explain these,\nbut don't use the term.\n\nSomething like the patch below uses the term. There's also a lot of\nduplication between the reading/writing paragraphs that could be\ncondensed (but I didn't do it here).\n\ndiff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc\nindex 8d080e301b..18cee89f84 100644\n--- a/Documentation/git-config.adoc\n+++ b/Documentation/git-config.adoc\n@@ -40,16 +40,14 @@ outgoing values are canonicalize-able under the given <type>.  If no\n unset an existing `--type` specifier with `--no-type`.\n \n When reading, the values are read from the system, global and\n-repository local configuration files by default, and options\n-`--system`, `--global`, `--local`, `--worktree` and\n-`--file <filename>` can be used to tell the command to read from only\n+repository local configuration files by default. Provide a\n+`<file-option>` (`--system`, `--global`, `--local`, `--worktree`,\n+or `--file <filename>`) to tell the command to read from only\n that location (see <<FILES>>).\n \n When writing, the new value is written to the repository local\n-configuration file by default, and options `--system`, `--global`,\n-`--worktree`, `--file <filename>` can be used to tell the command to\n-write to that location (you can say `--local` but that is the\n-default).\n+configuration file by default. A `<file-options>` can be used to tell\n+the command to write to that location.\n \n This command will fail with non-zero status upon error.  Some exit\n codes are:\n\n\nI also considered that the options themselves should be grouped as\nsub-entries of a <file-options>:: entry, but I think that may create\nother awkwardness.\n\nThere is also --blob, which affects the source/dest of config, but isn't\nreally a \"file\" option. It is really more of a \"location\" option (and\nthat is what it is called in the macro grouping within the code, though\nthat is never exposed to the user).\n\n>  * The SYNOPSIS section also refers to <display-option> for many\n>    operations; I have no idea what it means.  I left a needswork\n>    comment there.  We should either clarify it in a similar way, or\n>    remove it if it does not refer to anything.\n\nIt comes from 14970509c6 (builtin/config: introduce \"list\" subcommand,\n2024-05-06), and there's similar macro magic. It really just means\n\"stuff that changes the list output\".\n\nI think the manpage could probably be rewritten to focus on the\ndifferent command modes, and have a section for \"here are the useful\noptions in list mode\". Whereas historically, \"--list\" was just another\noption. That would be a much bigger rewrite of the page, though.\n\n-Peff\n"},{"id":"552483","messageId":"20260910190513.GB903701@coredump.intra.peff.net","threadId":"66302","inReplyTo":"20260910175416.115280-1-ub4nal@mail.ru","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-10T19:05:13Z","receivedAt":"2026-09-10T19:05:15Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 08:54:15PM +0300, Vsevolod Myalitsin wrote:\n\n> > I'm really not sure why anybody would use those other flags, though (or\n> > even --system, for that matter). After reading the thread again, I get\n> > why we want \"--global\" for advice that only affects new repository\n> > creation (like defaultBranchName), since otherwise it could never have\n> > any effect. But why would you ever want --system?\n> \n> I initially looked at Junio's suggestion and, based on his experience,\n> didn't argue with it, and then I didn't come back to that message. I\n> think the patch should contain not + enum config_scope scope_hint; but\n> + bool is_global_hint;, since I myself can't find any scenarios where\n> advice should be disabled at the system level.\n\nYeah, it feels like handling arbitrary scopes is introducing all of\nthese extra questions. But all we really need is that original bool you\nhad. I think there's some YAGNI principle here, too. Later if somebody\ncomes along and really wants to advise the user to use \"git config\n--system\", they can do the bool-to-scope conversion then. I'd be\nsurprised if that happens.\n\n-Peff\n"},{"id":"552489","messageId":"xmqqh5jwevbm.fsf@gitster.g","threadId":"66302","inReplyTo":"20260910190345.GA903701@coredump.intra.peff.net","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-10T19:54:21Z","receivedAt":"2026-09-10T19:54:24Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> I kind of wonder if _all_ advice should just say \"--global\". I cannot\n> think of an advice flag that is really repo specific. They are about\n> silencing extra help because the _user_ understands the situation and\n> wants Git to be less chatty.\n\nI think there are two things in play.\n\n * If applicability of a piece of advice depends on the workflow\n   employed, and a user who works on multiple projects that use\n   different workflows, set of advice messages may want to be\n   squelched per project, hence \"--global\" may not be appropriate.\n\n * \"I, a physical single person, understand this piece of advice\" is\n   inherently per user, so squelching a piece of advice that the\n   physical single person understands globally may make sense very\n   well.\n\nIn hindsight, the latter argument should have been given more\nweight, but I think the primary thinking back when we designed the\ncustomizable advice messages was instead the former.\n\n"},{"id":"552490","messageId":"20260910201111.GA919731@coredump.intra.peff.net","threadId":"66302","inReplyTo":"xmqqh5jwevbm.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-10T20:11:11Z","receivedAt":"2026-09-10T20:11:13Z","isPatch":true,"body":"On Thu, Sep 10, 2026 at 12:54:21PM -0700, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > I kind of wonder if _all_ advice should just say \"--global\". I cannot\n> > think of an advice flag that is really repo specific. They are about\n> > silencing extra help because the _user_ understands the situation and\n> > wants Git to be less chatty.\n> \n> I think there are two things in play.\n> \n>  * If applicability of a piece of advice depends on the workflow\n>    employed, and a user who works on multiple projects that use\n>    different workflows, set of advice messages may want to be\n>    squelched per project, hence \"--global\" may not be appropriate.\n> \n>  * \"I, a physical single person, understand this piece of advice\" is\n>    inherently per user, so squelching a piece of advice that the\n>    physical single person understands globally may make sense very\n>    well.\n> \n> In hindsight, the latter argument should have been given more\n> weight, but I think the primary thinking back when we designed the\n> customizable advice messages was instead the former.\n\nYeah, my contention is that the first thing doesn't really exist. But I\nadmit I didn't carefully go through the list of advice looking for\ncounter-examples.\n\nI'd be surprised if anybody really thought carefully about it, though.\nWhen I introduced advice.* in 2009 (geez, has it really been that long?)\nI had assumed people would just set it in their user config. The actual\n\"git config\" command advice came much later, but I don't see any\ndiscussion of global vs local in that thread:\n\n  https://lore.kernel.org/git/pull.548.git.1581311049547.gitgitgadget@gmail.com/\n\nAmusingly that thread also touches on some of the \"could we just convert\neverything to advise_if_enabled()\" issues we've discussed here. I had\nzero recollection of it, despite participating.\n\n-Peff\n"},{"id":"552491","messageId":"xmqqcxuketuz.fsf@gitster.g","threadId":"66302","inReplyTo":"20260910201111.GA919731@coredump.intra.peff.net","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-10T20:25:56Z","receivedAt":"2026-09-10T20:26:00Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> I'd be surprised if anybody really thought carefully about it, though.\n> When I introduced advice.* in 2009 (geez, has it really been that long?)\n> I had assumed people would just set it in their user config. The actual\n> \"git config\" command advice came much later, but I don't see any\n> discussion of global vs local in that thread:\n>\n>   https://lore.kernel.org/git/pull.548.git.1581311049547.gitgitgadget@gmail.com/\n>\n> Amusingly that thread also touches on some of the \"could we just convert\n> everything to advise_if_enabled()\" issues we've discussed here. I had\n> zero recollection of it, despite participating.\n\nI do not think I added much input into the topic at the\nphilosophical design level---just the usual usability and\ncorrectness review.  No wonder I do not recall anything particular I\ncontributed to the discussion there ;-)\n\nIt is very much understandable if we didn't mean the \"use 'git\nconfig advice.foo false' to disable\" as a cut-and-paste ready\ninstruction, and rather meant as a general instruction that any\nintelligent users would tweak for their own situation.  And it is\nnot surprising, from such a stance, the 'git config' hint would not\ncome with any scope indicator.\n"},{"id":"552621","messageId":"20260912081246.133514-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"xmqqcxuketuz.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-12T08:12:45Z","receivedAt":"2026-09-12T08:30:31Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> It is very much understandable if we didn't mean the \"use 'git\n> config advice.foo false' to disable\" as a cut-and-paste ready\n> instruction, and rather meant as a general instruction that any\n> intelligent users would tweak for their own situation.  And it is\n> not surprising, from such a stance, the 'git config' hint would not\n> come with any scope indicator.\n\nI think that since advice.* was originally assumed to be disabled\nglobally (as Jeff mentions, he expected it to be set in the user\nconfig), adding \"--global\" to the hint is a good solution.  It makes\nthe hint actually cut-and-paste ready while still matching the\noriginal intent.\n\nAs for \"--system\", \"--worktree\" and the like, I don't think it makes\nsense to support them until there is a proven need.  I propose to\nchoose between local and global via a boolean flag, and treat all the\nother scopes as YAGNI for now.\n\nThanks.\n"},{"id":"552645","messageId":"xmqq8q55863e.fsf@gitster.g","threadId":"66302","inReplyTo":"20260912081246.133514-1-ub4nal@mail.ru","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-13T16:32:37Z","receivedAt":"2026-09-13T16:32:40Z","isPatch":true,"body":"Vsevolod Myalitsin <ub4nal@mail.ru> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> It is very much understandable if we didn't mean the \"use 'git\n>> config advice.foo false' to disable\" as a cut-and-paste ready\n>> instruction, and rather meant as a general instruction that any\n>> intelligent users would tweak for their own situation.  And it is\n>> not surprising, from such a stance, the 'git config' hint would not\n>> come with any scope indicator.\n>\n> I think that since advice.* was originally assumed to be disabled\n> globally (as Jeff mentions, he expected it to be set in the user\n> config), adding \"--global\" to the hint is a good solution.  It makes\n> the hint actually cut-and-paste ready while still matching the\n> original intent.\n\nThe original intent was more like \"the users are intelligent enough\nto be able to decide which scope they want to use\", I think.  I\nagree that even with \"--global\" they can still cut-and-paste and\ntweak if they wanted to, so I am OK with that move, but my point was\nit probably is not even needed to mark each ones for which scope\nthey are suggested to be set (iow, we can just change the message to\nalways say \"--global\" without changing anything else).\n\nThanks.\n\n"},{"id":"552722","messageId":"20260914170034.GE32247@peff.net","threadId":"66302","inReplyTo":"xmqq8q55863e.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-14T17:00:34Z","receivedAt":"2026-09-14T17:00:35Z","isPatch":true,"body":"On Sun, Sep 13, 2026 at 09:32:37AM -0700, Junio C Hamano wrote:\n\n> > I think that since advice.* was originally assumed to be disabled\n> > globally (as Jeff mentions, he expected it to be set in the user\n> > config), adding \"--global\" to the hint is a good solution.  It makes\n> > the hint actually cut-and-paste ready while still matching the\n> > original intent.\n> \n> The original intent was more like \"the users are intelligent enough\n> to be able to decide which scope they want to use\", I think.  I\n> agree that even with \"--global\" they can still cut-and-paste and\n> tweak if they wanted to, so I am OK with that move, but my point was\n> it probably is not even needed to mark each ones for which scope\n> they are suggested to be set (iow, we can just change the message to\n> always say \"--global\" without changing anything else).\n\nYeah, I was hinting that I think suggesting --global for all advice\nwould be fine. It's possible some particular advice would be better set\nwithin a repo, but I kind of doubt it. And if we do find one, I think it\nwould be the exception, and then we could introduce a hint flag for that\none bit of advice in the other direction. :)\n\n-Peff\n"},{"id":"552728","messageId":"xmqqqziv4nk7.fsf@gitster.g","threadId":"66302","inReplyTo":"20260914170034.GE32247@peff.net","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-14T19:53:28Z","receivedAt":"2026-09-14T19:53:32Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> On Sun, Sep 13, 2026 at 09:32:37AM -0700, Junio C Hamano wrote:\n>\n>> > I think that since advice.* was originally assumed to be disabled\n>> > globally (as Jeff mentions, he expected it to be set in the user\n>> > config), adding \"--global\" to the hint is a good solution.  It makes\n>> > the hint actually cut-and-paste ready while still matching the\n>> > original intent.\n>> \n>> The original intent was more like \"the users are intelligent enough\n>> to be able to decide which scope they want to use\", I think.  I\n>> agree that even with \"--global\" they can still cut-and-paste and\n>> tweak if they wanted to, so I am OK with that move, but my point was\n>> it probably is not even needed to mark each ones for which scope\n>> they are suggested to be set (iow, we can just change the message to\n>> always say \"--global\" without changing anything else).\n>\n> Yeah, I was hinting that I think suggesting --global for all advice\n> would be fine. It's possible some particular advice would be better set\n> within a repo, but I kind of doubt it. And if we do find one, I think it\n> would be the exception, and then we could introduce a hint flag for that\n> one bit of advice in the other direction. :)\n\nYup, I love the simplicity of that approach.\n"},{"id":"552730","messageId":"xmqq33vb4hma.fsf@gitster.g","threadId":"66302","inReplyTo":"xmqqqziv4nk7.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-14T22:01:49Z","receivedAt":"2026-09-14T22:01:52Z","isPatch":true,"body":"> Jeff King <peff@peff.net> writes:\n>\n>> Yeah, I was hinting that I think suggesting --global for all advice\n>> would be fine. It's possible some particular advice would be better set\n>> within a repo, but I kind of doubt it. And if we do find one, I think it\n>> would be the exception, and then we could introduce a hint flag for that\n>> one bit of advice in the other direction. :)\n\nSo to conclude the topic, we would only need this?\n\n----- >8 -----\nSubject: [PATCH v5 1/1] advice: give cut-and-pasteable advice to squelch\n\nAdvice messages that the advise_if_enabled() helper emits tell\nthe user how to squelch a particular piece of advice by setting a\nconfiguration variable.  The message it gives says:\n\n    hint: Disable this message with \"git config set advice.FOO false\"\n\nHowever, cutting and pasting the given hint would set the\nconfiguration variable in the per-repository configuration file\n(which is the default behavior for 'git config set').  As the user\nmost likely sets it after seeing advice and understanding its\nramifications, the choice of squelching or continuing to see the\nadvice message is better controlled per-user, not per-repository.\n\nIn addition, some advice, such as advice.defaultBranchName, is\napplicable only once before a new repository is created, so setting\nit in the per-repository configuration file is far too late.\n\nAdd '--global' to the 'git config set' command line so that the\nconfiguration is set for the user rather than per repository.\n\nInitial-work-by: Vsevolod Myalitsin <ub4nal@mail.ru>\nHelped-by: Jeff King <peff@peff.net>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n advice.c                        | 2 +-\n t/t0018-advice.sh               | 2 +-\n t/t3200-branch.sh               | 2 +-\n t/t3404-rebase-interactive.sh   | 6 +++---\n t/t3501-revert-cherry-pick.sh   | 2 +-\n t/t3507-cherry-pick-conflict.sh | 4 ++--\n t/t3602-rm-sparse-checkout.sh   | 2 +-\n t/t3700-add.sh                  | 6 +++---\n t/t3705-add-sparse-checkout.sh  | 2 +-\n t/t7002-mv-sparse-checkout.sh   | 4 ++--\n t/t7004-tag.sh                  | 2 +-\n t/t7400-submodule-basic.sh      | 2 +-\n 12 files changed, 18 insertions(+), 18 deletions(-)\n\ndiff --git c/advice.c w/advice.c\nindex 63bf8b0c5f..d81afc80d1 100644\n--- c/advice.c\n+++ w/advice.c\n@@ -96,7 +96,7 @@ static struct {\n \n static const char turn_off_instructions[] =\n N_(\"\\n\"\n-   \"Disable this message with \\\"git config set advice.%s false\\\"\");\n+   \"Disable this message with \\\"git config set --global advice.%s false\\\"\");\n \n static void vadvise(const char *advice, int display_instructions,\n \t\t    const char *key, va_list params)\ndiff --git c/t/t0018-advice.sh w/t/t0018-advice.sh\nindex f68e08d0b1..8f05b5ae6c 100755\n--- c/t/t0018-advice.sh\n+++ w/t/t0018-advice.sh\n@@ -10,7 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n test_expect_success 'advice should be printed when config variable is unset' '\n \tcat >expect <<-\\EOF &&\n \thint: This is a piece of advice\n-\thint: Disable this message with \"git config set advice.nestedTag false\"\n+\thint: Disable this message with \"git config set --global advice.nestedTag false\"\n \tEOF\n \ttest-tool advise \"This is a piece of advice\" 2>actual &&\n \ttest_cmp expect actual\ndiff --git c/t/t3200-branch.sh w/t/t3200-branch.sh\nindex cdb6c6a634..0d7d9d3957 100755\n--- c/t/t3200-branch.sh\n+++ w/t/t3200-branch.sh\n@@ -1751,7 +1751,7 @@ test_expect_success 'errors if given a bad branch name' '\n \tcat <<-EOF >expect &&\n \tfatal: ${SQ}foo..bar${SQ} is not a valid branch name\n \thint: See ${SQ}git help check-ref-format${SQ}\n-\thint: Disable this message with \"git config set advice.refSyntax false\"\n+\thint: Disable this message with \"git config set --global advice.refSyntax false\"\n \tEOF\n \ttest_must_fail git branch foo..bar >actual 2>&1 &&\n \ttest_cmp expect actual\ndiff --git c/t/t3404-rebase-interactive.sh w/t/t3404-rebase-interactive.sh\nindex 8c63682b7f..7dc6328502 100755\n--- c/t/t3404-rebase-interactive.sh\n+++ w/t/t3404-rebase-interactive.sh\n@@ -2461,20 +2461,20 @@ test_expect_success 'non-merge commands reject merge commits' '\n \terror: ${SQ}pick${SQ} does not accept merge commits\n \thint: ${SQ}pick${SQ} does not take a merge commit. If you wanted to\n \thint: replay the merge, use ${SQ}merge -C${SQ} on the commit.\n-\thint: Disable this message with \"git config set advice.rebaseTodoError false\"\n+\thint: Disable this message with \"git config set --global advice.rebaseTodoError false\"\n \terror: invalid line 1: pick $oid\n \terror: ${SQ}reword${SQ} does not accept merge commits\n \thint: ${SQ}reword${SQ} does not take a merge commit. If you wanted to\n \thint: replay the merge and reword the commit message, use\n \thint: ${SQ}merge -c${SQ} on the commit\n-\thint: Disable this message with \"git config set advice.rebaseTodoError false\"\n+\thint: Disable this message with \"git config set --global advice.rebaseTodoError false\"\n \terror: invalid line 2: reword $oid\n \terror: ${SQ}edit${SQ} does not accept merge commits\n \thint: ${SQ}edit${SQ} does not take a merge commit. If you wanted to\n \thint: replay the merge, use ${SQ}merge -C${SQ} on the commit, and then\n \thint: ${SQ}break${SQ} to give the control back to you so that you can\n \thint: do ${SQ}git commit --amend && git rebase --continue${SQ}.\n-\thint: Disable this message with \"git config set advice.rebaseTodoError false\"\n+\thint: Disable this message with \"git config set --global advice.rebaseTodoError false\"\n \terror: invalid line 3: edit $oid\n \terror: cannot squash merge commit into another commit\n \terror: invalid line 4: fixup $oid\ndiff --git c/t/t3501-revert-cherry-pick.sh w/t/t3501-revert-cherry-pick.sh\nindex 939e7a16a6..2abbf071ce 100755\n--- c/t/t3501-revert-cherry-pick.sh\n+++ w/t/t3501-revert-cherry-pick.sh\n@@ -177,7 +177,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 set advice.mergeConflict false\"\n+\thint: Disable this message with \"git config set --global 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 c/t/t3507-cherry-pick-conflict.sh w/t/t3507-cherry-pick-conflict.sh\nindex c767e4ad3d..5be94493c1 100755\n--- c/t/t3507-cherry-pick-conflict.sh\n+++ w/t/t3507-cherry-pick-conflict.sh\n@@ -60,7 +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 set advice.mergeConflict false\"\n+\thint: Disable this message with \"git config set --global advice.mergeConflict false\"\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n@@ -75,7 +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 set advice.mergeConflict false\\\"\n+\thint: Disable this message with \\\"git config set --global advice.mergeConflict false\\\"\n \tEOF\n \ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n \ndiff --git c/t/t3602-rm-sparse-checkout.sh w/t/t3602-rm-sparse-checkout.sh\nindex 252df28bbf..bccb31a5a1 100755\n--- c/t/t3602-rm-sparse-checkout.sh\n+++ w/t/t3602-rm-sparse-checkout.sh\n@@ -20,7 +20,7 @@ test_expect_success 'setup' \"\n \thint: If you intend to update such entries, try one of the following:\n \thint: * Use the --sparse option.\n \thint: * Disable or modify the sparsity rules.\n-\thint: Disable this message with \\\"git config set advice.updateSparsePath false\\\"\n+\thint: Disable this message with \\\"git config set --global advice.updateSparsePath false\\\"\n \tEOF\n \n \techo b | cat sparse_error_header - >sparse_entry_b_error &&\ndiff --git c/t/t3700-add.sh w/t/t3700-add.sh\nindex 2947bf9a6b..59e48482a2 100755\n--- c/t/t3700-add.sh\n+++ w/t/t3700-add.sh\n@@ -31,7 +31,7 @@ test_expect_success 'Test with no pathspecs' '\n \tcat >expect <<-EOF &&\n \tNothing specified, nothing added.\n \thint: Maybe you wanted to say ${SQ}git add .${SQ}?\n-\thint: Disable this message with \"git config set advice.addEmptyPathspec false\"\n+\thint: Disable this message with \"git config set --global advice.addEmptyPathspec false\"\n \tEOF\n \tgit add 2>actual &&\n \ttest_cmp expect actual\n@@ -386,7 +386,7 @@ test_expect_success '\"git add\" a embedded repository' '\n \t\thint: \tgit rm --cached inner1\n \t\thint:\n \t\thint: See \"git help submodule\" for more information.\n-\t\thint: Disable this message with \"git config set advice.addEmbeddedRepo false\"\n+\t\thint: Disable this message with \"git config set --global advice.addEmbeddedRepo false\"\n \t\twarning: adding embedded git repository: inner2\n \t\tEOF\n \t\ttest_cmp expect actual\n@@ -425,7 +425,7 @@ cat >expect.err <<\\EOF\n The following paths are ignored by one of your .gitignore files:\n ignored-file\n hint: Use -f if you really want to add them.\n-hint: Disable this message with \"git config set advice.addIgnoredFile false\"\n+hint: Disable this message with \"git config set --global advice.addIgnoredFile false\"\n EOF\n cat >expect.out <<\\EOF\n add 'track-this'\ndiff --git c/t/t3705-add-sparse-checkout.sh w/t/t3705-add-sparse-checkout.sh\nindex 975f9218b0..2e97e3c003 100755\n--- c/t/t3705-add-sparse-checkout.sh\n+++ w/t/t3705-add-sparse-checkout.sh\n@@ -54,7 +54,7 @@ test_expect_success 'setup' \"\n \thint: If you intend to update such entries, try one of the following:\n \thint: * Use the --sparse option.\n \thint: * Disable or modify the sparsity rules.\n-\thint: Disable this message with \\\"git config set advice.updateSparsePath false\\\"\n+\thint: Disable this message with \\\"git config set --global advice.updateSparsePath false\\\"\n \tEOF\n \n \techo sparse_entry | cat sparse_error_header - >sparse_entry_error &&\ndiff --git c/t/t7002-mv-sparse-checkout.sh w/t/t7002-mv-sparse-checkout.sh\nindex 9c0e82ba31..666317fdf9 100755\n--- c/t/t7002-mv-sparse-checkout.sh\n+++ w/t/t7002-mv-sparse-checkout.sh\n@@ -32,7 +32,7 @@ test_expect_success 'setup' \"\n \thint: If you intend to update such entries, try one of the following:\n \thint: * Use the --sparse option.\n \thint: * Disable or modify the sparsity rules.\n-\thint: Disable this message with \\\"git config set advice.updateSparsePath false\\\"\n+\thint: Disable this message with \\\"git config set --global advice.updateSparsePath false\\\"\n \tEOF\n \n \tcat >dirty_error_header <<-EOF &&\n@@ -45,7 +45,7 @@ test_expect_success 'setup' \"\n \thint: To correct the sparsity of these paths, do the following:\n \thint: * Use \\\"git add --sparse <paths>\\\" to update the index\n \thint: * Use \\\"git sparse-checkout reapply\\\" to apply the sparsity rules\n-\thint: Disable this message with \\\"git config set advice.updateSparsePath false\\\"\n+\thint: Disable this message with \\\"git config set --global advice.updateSparsePath false\\\"\n \tEOF\n \"\n \ndiff --git c/t/t7004-tag.sh w/t/t7004-tag.sh\nindex 8c795d7218..49cdb6fdb0 100755\n--- c/t/t7004-tag.sh\n+++ w/t/t7004-tag.sh\n@@ -1887,7 +1887,7 @@ test_expect_success 'recursive tagging should give advice' '\n \thint: already a tag. If you meant to tag the object that it points to, use:\n \thint:\n \thint: \tgit tag -f nested annotated-v4.0^{}\n-\thint: Disable this message with \"git config set advice.nestedTag false\"\n+\thint: Disable this message with \"git config set --global advice.nestedTag false\"\n \tEOF\n \tgit tag -m nested nested annotated-v4.0 2>actual &&\n \ttest_cmp expect actual\ndiff --git c/t/t7400-submodule-basic.sh w/t/t7400-submodule-basic.sh\nindex eefdecb0bd..36ff5b9546 100755\n--- c/t/t7400-submodule-basic.sh\n+++ w/t/t7400-submodule-basic.sh\n@@ -231,7 +231,7 @@ test_expect_success 'submodule add to .gitignored path fails' '\n \t\tThe following paths are ignored by one of your .gitignore files:\n \t\tsubmod\n \t\thint: Use -f if you really want to add them.\n-\t\thint: Disable this message with \"git config set advice.addIgnoredFile false\"\n+\t\thint: Disable this message with \"git config set --global advice.addIgnoredFile false\"\n \t\tEOF\n \t\t# Does not use test_commit due to the ignore\n \t\techo \"*\" > .gitignore &&\n"},{"id":"552811","messageId":"20260917140350.44760-1-ub4nal@mail.ru","threadId":"66302","inReplyTo":"xmqq33vb4hma.fsf@gitster.g","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Vsevolod Myalitsin","fromEmail":"ub4nal@mail.ru","sentAt":"2026-09-17T14:03:50Z","receivedAt":"2026-09-17T12:31:12Z","isPatch":true,"body":"Junio C Hamano writes:\n> So to conclude the topic, we would only need this?\n\nYes, I think this is indeed where we were heading.\n\nHowever, during the discussion I really liked the idea of passing a pointer to the \"advice_setting\" to \"vadvise()\" instead of passing its individual fields. It seems like a cleaner interface, even though it is not directly related to this fix.\n\nWould it make sense to submit that change as a separate patch?\n"},{"id":"552813","messageId":"20260917132540.GA101514@peff.net","threadId":"66302","inReplyTo":"20260917140350.44760-1-ub4nal@mail.ru","subject":"Re: [PATCH v4 2/3] advice: introduce advice scoping mechanism","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-09-17T13:25:40Z","receivedAt":"2026-09-17T13:25:47Z","isPatch":true,"body":"On Thu, Sep 17, 2026 at 05:03:50PM +0300, Vsevolod Myalitsin wrote:\n\n> Junio C Hamano writes:\n> > So to conclude the topic, we would only need this?\n> \n> Yes, I think this is indeed where we were heading.\n\nLikewise, and the patch looks good to me from a quick read.\n\n> However, during the discussion I really liked the idea of passing a\n> pointer to the \"advice_setting\" to \"vadvise()\" instead of passing its\n> individual fields. It seems like a cleaner interface, even though it\n> is not directly related to this fix.\n> \n> Would it make sense to submit that change as a separate patch?\n\nI think so. I probably would not have looked into it as a cleanup on its\nown, but since we already spent time thinking about it, let's not waste\nthose brain cycles.\n\n-Peff\n"}]}