{"thread":{"id":"57159","subject":"[PATCH 0/7] help: test and fix small \"help -g\" regression","startedAt":"2021-12-28T15:36:22Z","lastAt":"2022-02-23T22:31:16Z","messageCount":29,"participants":["Ævar Arnfjörð Bjarmason","Eric Sunshine","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"445098","messageId":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":null,"subject":"[PATCH 0/7] help: test and fix small \"help -g\" regression","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:05Z","receivedAt":"2021-12-28T15:36:22Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a trivial regression in 17b3e515050 (Merge branch\n'nd/command-list' into nd/complete-config-vars, 2018-05-29) where we'd\noverly whitespace pad \"git help -g\", since the codepath moved to a\nfunction that assumed it needed to \"\\n\\n\"-pad multiple items being\nemitted, so we'd print an extra leading newline when printing one\nitem (as opposed to \"git help -a\").\n\nIn doing so I wanted to add regression tests, and to do that we first\nneed to make the format stable (\"git help -a\" will change depending on\nwhatever git-* you have in $PATH).\n\nThese are things I noticed when re-rolling my no-yet-picked-up series\nto move Documentation/technical/* to manpages[1]. An unsubmitted\nre-roll of this series depends on this one. I'll hold off on a\nre-submission of it until this series has graduated.\n\n1. https://lore.kernel.org/git/cover-v2-0.5-00000000000-20211212T194047Z-avarab@gmail.com/\n\nÆvar Arnfjörð Bjarmason (7):\n  help doc: add missing \"]\" to \"[-a|--all]\"\n  help.c: use puts() instead of printf{,_ln}() for consistency\n  help tests: test \"git\" and \"git help [-a|-g] spacing\n  help.c: split up list_all_cmds_help() function\n  help: error if [-a|-g|-c] and [-i|-m|-w] are combined\n  help: add --no-[external-commands|aliases] for use with --all\n  help: don't print \"\\n\" before single-section output\n\n Documentation/git-help.txt | 12 ++++-\n builtin/help.c             | 34 ++++++++++++--\n help.c                     | 37 ++++++++++++----\n help.h                     |  2 +-\n t/t0012-help.sh            | 91 ++++++++++++++++++++++++++++++++++++++\n 5 files changed, 161 insertions(+), 15 deletions(-)\n\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445099","messageId":"patch-1.7-652dae26bf4-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 1/7] help doc: add missing \"]\" to \"[-a|--all]\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:06Z","receivedAt":"2021-12-28T15:36:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a missing \"]\" to documentation added in 63eae83f8f3 (help: add \"-a\n--verbose\" to list all commands with synopsis, 2018-05-20). This made\nit seem as though \"--[no-]verbose\" can only be provided with \"--all\",\nnot \"-a\". The corresponding usage information in the C\ncode (\"builtin_help_usage\") does not have the same problem.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex 44ea63cc6d3..cf1d53e9499 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -8,7 +8,7 @@ git-help - Display help information about Git\n SYNOPSIS\n --------\n [verse]\n-'git help' [-a|--all [--[no-]verbose]]\n+'git help' [-a|--all] [--[no-]verbose]\n \t   [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445100","messageId":"patch-2.7-f84662469a3-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 2/7] help.c: use puts() instead of printf{,_ln}() for consistency","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:07Z","receivedAt":"2021-12-28T15:36:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change code in \"help.c\" that used printf_ln() without format\nspecifiers to use puts() instead, as other existing code in the file\ndoes. Let's also change related code to use puts() instead of the\nequivalent of calling \"printf\" with a \"%s\\n\" format.\n\nThis formatting-only change will make a subsequent functional change\neasier to read, as it'll be changing code that's consistently using\nthe same functions to do the same things.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 973e47cdc30..0ba9b866f03 100644\n--- a/help.c\n+++ b/help.c\n@@ -124,7 +124,8 @@ static void print_cmd_by_category(const struct category_description *catdesc,\n \t\tuint32_t mask = catdesc[i].category;\n \t\tconst char *desc = catdesc[i].desc;\n \n-\t\tprintf(\"\\n%s\\n\", _(desc));\n+\t\tputchar('\\n');\n+\t\tputs(_(desc));\n \t\tprint_command_list(cmds, mask, longest);\n \t}\n \tfree(cmds);\n@@ -317,7 +318,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n \t}\n \n \tif (other_cmds->cnt) {\n-\t\tprintf_ln(_(\"git commands available from elsewhere on your $PATH\"));\n+\t\tputs(_(\"git commands available from elsewhere on your $PATH\"));\n \t\tputchar('\\n');\n \t\tpretty_print_cmdnames(other_cmds, colopts);\n \t\tputchar('\\n');\n@@ -439,7 +440,7 @@ void list_all_cmds_help(void)\n \tstruct cmdname_help *aliases;\n \tint i, longest;\n \n-\tprintf_ln(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n \tprint_cmd_by_category(main_categories, &longest);\n \n \tlist_all_other_cmds(&others);\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445101","messageId":"patch-3.7-3956937cf3b-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 3/7] help tests: test \"git\" and \"git help [-a|-g] spacing","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:08Z","receivedAt":"2021-12-28T15:36:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"There's logic in \"help.c\"'s \"print_cmd_by_category()\" to emit \"help\"\noutput with particular spacing, which doesn't make much sense when\nemitting only one section with \"help -g\".\n\nLet's add tests for the current spacing in preparation for a\nsubsequent whitespace formatting fix, and make sure that that fix\ndoesn't cause regressions for the \"git\" and \"git help\" output.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0012-help.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 45 insertions(+)\n\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex 91b68c74a15..6ac293c19ed 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -138,6 +138,51 @@ test_expect_success 'git help --config-sections-for-completion' '\n \ttest_cmp human.munged sections\n '\n \n+test_section_spacing () {\n+\tcat >expect &&\n+\t\"$@\" >out &&\n+\tgrep -E \"(^[^ ]|^$)\" out >actual\n+}\n+\n+test_section_spacing_trailer () {\n+\ttest_section_spacing \"$@\" &&\n+\ttest_expect_code 1 git >out &&\n+\tsed -n '/list available subcommands/,$p' <out >>expect\n+}\n+\n+\n+for cmd in git \"git help\"\n+do\n+\ttest_expect_success \"'$cmd' section spacing\" '\n+\t\ttest_section_spacing_trailer git help <<-\\EOF &&\n+\t\tusage: git [--version] [--help] [-C <path>] [-c <name>=<value>]\n+\n+\t\tThese are common Git commands used in various situations:\n+\n+\t\tstart a working area (see also: git help tutorial)\n+\n+\t\twork on the current change (see also: git help everyday)\n+\n+\t\texamine the history and state (see also: git help revisions)\n+\n+\t\tgrow, mark and tweak your common history\n+\n+\t\tcollaborate (see also: git help workflows)\n+\n+\t\tEOF\n+\t\ttest_cmp expect actual\n+\t'\n+done\n+\n+test_expect_success \"'git help -g' section spacing\" '\n+\ttest_section_spacing_trailer git help -g <<-\\EOF &&\n+\n+\tThe Git concept guides are:\n+\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'generate builtin list' '\n \tgit --list-cmds=builtins >builtins\n '\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445102","messageId":"patch-4.7-f040dd549b4-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 4/7] help.c: split up list_all_cmds_help() function","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:09Z","receivedAt":"2021-12-28T15:36:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Split up the listing of commands and aliases from\nlist_all_cmds_help(). This will make a subsequent functional change\nsmaller.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c | 27 ++++++++++++++++++++-------\n 1 file changed, 20 insertions(+), 7 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 0ba9b866f03..ef1aa26efa6 100644\n--- a/help.c\n+++ b/help.c\n@@ -433,15 +433,10 @@ static int get_alias(const char *var, const char *value, void *data)\n \treturn 0;\n }\n \n-void list_all_cmds_help(void)\n+static void list_all_cmds_help_external_commands(void)\n {\n \tstruct string_list others = STRING_LIST_INIT_DUP;\n-\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n-\tstruct cmdname_help *aliases;\n-\tint i, longest;\n-\n-\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n-\tprint_cmd_by_category(main_categories, &longest);\n+\tint i;\n \n \tlist_all_other_cmds(&others);\n \tif (others.nr)\n@@ -449,6 +444,13 @@ void list_all_cmds_help(void)\n \tfor (i = 0; i < others.nr; i++)\n \t\tprintf(\"   %s\\n\", others.items[i].string);\n \tstring_list_clear(&others, 0);\n+}\n+\n+static void list_all_cmds_help_aliases(int longest)\n+{\n+\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n+\tstruct cmdname_help *aliases;\n+\tint i;\n \n \tgit_config(get_alias, &alias_list);\n \tstring_list_sort(&alias_list);\n@@ -474,6 +476,17 @@ void list_all_cmds_help(void)\n \tstring_list_clear(&alias_list, 1);\n }\n \n+void list_all_cmds_help(void)\n+{\n+\tint longest;\n+\n+\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tprint_cmd_by_category(main_categories, &longest);\n+\n+\tlist_all_cmds_help_external_commands();\n+\tlist_all_cmds_help_aliases(longest);\n+}\n+\n int is_in_cmdlist(struct cmdnames *c, const char *s)\n {\n \tint i;\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445103","messageId":"patch-5.7-12ff152bd57-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 5/7] help: error if [-a|-g|-c] and [-i|-m|-w] are combined","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:10Z","receivedAt":"2021-12-28T15:36:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add more sanity checking to \"git help\" usage by erroring out if these\nman viewer options are combined with incompatible command-modes that\nwill never use these documentation viewers.\n\nThis continues the work started in d35d03cf93e (help: simplify by\nmoving to OPT_CMDMODE(), 2021-09-22) of adding more sanity checking to\n\"git help\". Doing this allows us to clarify the \"SYNOPSIS\" in the\ndocumentation, and the \"git help -h\" output.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt |  2 +-\n builtin/help.c             | 20 ++++++++++++++++++--\n t/t0012-help.sh            | 10 ++++++++++\n 3 files changed, 29 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex cf1d53e9499..61d52d30f6c 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git help' [-a|--all] [--[no-]verbose]\n-\t   [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n+'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n \ndiff --git a/builtin/help.c b/builtin/help.c\nindex d387131dd83..125f50f1bb0 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -75,8 +75,8 @@ static struct option builtin_help_options[] = {\n };\n \n static const char * const builtin_help_usage[] = {\n-\tN_(\"git help [-a|--all] [--[no-]verbose]]\\n\"\n-\t   \"         [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n+\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n+\tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n \tN_(\"git help [-g|--guides]\"),\n \tN_(\"git help [-c|--config]\"),\n \tNULL\n@@ -581,6 +581,13 @@ static void no_extra_argc(int argc)\n \t\t\t      builtin_help_usage, builtin_help_options);\n }\n \n+static void no_format(void)\n+{\n+\tif (help_format != HELP_FORMAT_NONE)\n+\t\tusage_msg_opt(_(\"[-a|--all] cannot be combined with [[-i|--info] [-m|--man] [-w|--web]]\"),\n+\t\t\t      builtin_help_usage, builtin_help_options);\n+}\n+\n int cmd_help(int argc, const char **argv, const char *prefix)\n {\n \tint nongit;\n@@ -593,6 +600,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \n \tswitch (cmd_mode) {\n \tcase HELP_ACTION_ALL:\n+\t\tno_format();\n \t\tif (verbose) {\n \t\t\tsetup_pager();\n \t\t\tlist_all_cmds_help();\n@@ -605,19 +613,27 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \t\tbreak;\n \tcase HELP_ACTION_GUIDES:\n \t\tno_extra_argc(argc);\n+\t\tno_format();\n+\n \t\tlist_guides_help();\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_FOR_COMPLETION:\n \t\tno_extra_argc(argc);\n+\t\tno_format();\n+\n \t\tlist_config_help(SHOW_CONFIG_VARS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:\n \t\tno_extra_argc(argc);\n+\t\tno_format();\n+\n \t\tlist_config_help(SHOW_CONFIG_SECTIONS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG:\n \t\tno_extra_argc(argc);\n+\t\tno_format();\n+\n \t\tsetup_pager();\n \t\tlist_config_help(SHOW_CONFIG_HUMAN);\n \t\tprintf(\"\\n%s\\n\", _(\"'git help config' for more information\"));\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex 6ac293c19ed..a8c603abd44 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -46,6 +46,16 @@ test_expect_success 'invalid usage' '\n \ttest_expect_code 129 git help --config-sections-for-completion add\n '\n \n+for opt in '-a' '-g' '-c' '--config-for-completion' '--config-sections-for-completion'\n+do\n+\ttest_expect_success \"invalid usage of '$opt' with [-i|-m|-w]\" '\n+\t\tgit help $opt &&\n+\t\ttest_expect_code 129 git help $opt -i &&\n+\t\ttest_expect_code 129 git help $opt -m &&\n+\t\ttest_expect_code 129 git help $opt -w\n+\t'\n+done\n+\n test_expect_success \"works for commands and guides by default\" '\n \tconfigure_help &&\n \tgit help status &&\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445104","messageId":"patch-6.7-a5ef9f69530-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 6/7] help: add --no-[external-commands|aliases] for use with --all","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:11Z","receivedAt":"2021-12-28T15:36:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add the ability to only emit git's own usage information under\n--all. This also allows us to extend the \"test_section_spacing\" tests\nadded in a preceding commit to test \"git help --all\"\noutput.\n\nPreviously we could not do that, as the tests might find a git-*\ncommand in the \"$PATH\", which would make the output differ from one\nsetup to another.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt | 10 +++++++++-\n builtin/help.c             | 16 ++++++++++++++--\n help.c                     |  8 +++++---\n help.h                     |  2 +-\n t/t0012-help.sh            | 37 +++++++++++++++++++++++++++++++++++++\n 5 files changed, 66 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex 61d52d30f6c..9307445c333 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -8,7 +8,7 @@ git-help - Display help information about Git\n SYNOPSIS\n --------\n [verse]\n-'git help' [-a|--all] [--[no-]verbose]\n+'git help' [-a|--all] [--[no-]verbose] [--[no-](external-commands|aliases)]\n 'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n@@ -49,6 +49,14 @@ OPTIONS\n \tPrints all the available commands on the standard output. This\n \toption overrides any given command or guide name.\n \n+--no-external-commands::\n+\tWhen used with `--all`, exclude the listing of external \"git-*\"\n+\tcommands found in the `$PATH`.\n+\n+--no-aliases::\n+\tWhen used with `--all`, exclude the listing of configured\n+\taliases.\n+\n --verbose::\n \tWhen used with `--all` print description for all recognized\n \tcommands. This is the default.\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 125f50f1bb0..1131b437389 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -51,9 +51,14 @@ static const char *html_path;\n static int verbose = 1;\n static enum help_format help_format = HELP_FORMAT_NONE;\n static int exclude_guides;\n+static int show_external_commands = -1;\n+static int show_aliases = -1;\n static struct option builtin_help_options[] = {\n \tOPT_CMDMODE('a', \"all\", &cmd_mode, N_(\"print all available commands\"),\n \t\t    HELP_ACTION_ALL),\n+\tOPT_BOOL(0, \"external-commands\", &show_external_commands,\n+\t\t N_(\"show external commands in --all?\")),\n+\tOPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all?\")),\n \tOPT_HIDDEN_BOOL(0, \"exclude-guides\", &exclude_guides, N_(\"exclude guides\")),\n \tOPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), HELP_FORMAT_MAN),\n \tOPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web browser\"),\n@@ -75,7 +80,7 @@ static struct option builtin_help_options[] = {\n };\n \n static const char * const builtin_help_usage[] = {\n-\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n+\tN_(\"git help [-a|--all] [--[no-]verbose]] [--[no-](external-commands|aliases)]\"),\n \tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n \tN_(\"git help [-g|--guides]\"),\n \tN_(\"git help [-c|--config]\"),\n@@ -598,12 +603,19 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \t\t\tbuiltin_help_usage, 0);\n \tparsed_help_format = help_format;\n \n+\tif (cmd_mode != HELP_ACTION_ALL &&\n+\t    (show_external_commands >= 0 ||\n+\t     show_aliases >= 0))\n+\t\tusage_msg_opt(_(\"the '--no-[external-commands|aliases]' options can only be used with '--all'\"),\n+\t\t\t      builtin_help_usage, builtin_help_options);\n+\n \tswitch (cmd_mode) {\n \tcase HELP_ACTION_ALL:\n \t\tno_format();\n \t\tif (verbose) {\n \t\t\tsetup_pager();\n-\t\t\tlist_all_cmds_help();\n+\t\t\tlist_all_cmds_help(show_external_commands,\n+\t\t\t\t\t   show_aliases);\n \t\t\treturn 0;\n \t\t}\n \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\ndiff --git a/help.c b/help.c\nindex ef1aa26efa6..2296f06ad9f 100644\n--- a/help.c\n+++ b/help.c\n@@ -476,15 +476,17 @@ static void list_all_cmds_help_aliases(int longest)\n \tstring_list_clear(&alias_list, 1);\n }\n \n-void list_all_cmds_help(void)\n+void list_all_cmds_help(int show_external_commands, int show_aliases)\n {\n \tint longest;\n \n \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n \tprint_cmd_by_category(main_categories, &longest);\n \n-\tlist_all_cmds_help_external_commands();\n-\tlist_all_cmds_help_aliases(longest);\n+\tif (show_external_commands)\n+\t\tlist_all_cmds_help_external_commands();\n+\tif (show_aliases)\n+\t\tlist_all_cmds_help_aliases(longest);\n }\n \n int is_in_cmdlist(struct cmdnames *c, const char *s)\ndiff --git a/help.h b/help.h\nindex 9d383f1a0b2..971a3ad855a 100644\n--- a/help.h\n+++ b/help.h\n@@ -20,7 +20,7 @@ static inline void mput_char(char c, unsigned int num)\n }\n \n void list_common_cmds_help(void);\n-void list_all_cmds_help(void);\n+void list_all_cmds_help(int show_external_commands, int show_aliases);\n void list_guides_help(void);\n \n void list_all_main_cmds(struct string_list *list);\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex a8c603abd44..c41b412e34a 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -54,6 +54,19 @@ do\n \t\ttest_expect_code 129 git help $opt -m &&\n \t\ttest_expect_code 129 git help $opt -w\n \t'\n+\n+\tif test \"$opt\" = \"-a\"\n+\tthen\n+\t\tcontinue\n+\tfi\n+\n+\ttest_expect_success \"invalid usage of '$opt' with --no-external-commands\" '\n+\t\ttest_expect_code 129 git help $opt --no-external-commands\n+\t'\n+\n+\ttest_expect_success \"invalid usage of '$opt' with --no-aliases\" '\n+\t\ttest_expect_code 129 git help $opt --no-external-commands\n+\t'\n done\n \n test_expect_success \"works for commands and guides by default\" '\n@@ -184,6 +197,30 @@ do\n \t'\n done\n \n+test_expect_success \"'git help -a' section spacing\" '\n+\ttest_section_spacing \\\n+\t\tgit help -a --no-external-commands --no-aliases <<-\\EOF &&\n+\tSee '\\''git help <command>'\\'' to read about a specific subcommand\n+\n+\tMain Porcelain Commands\n+\n+\tAncillary Commands / Manipulators\n+\n+\tAncillary Commands / Interrogators\n+\n+\tInteracting with Others\n+\n+\tLow-level Commands / Manipulators\n+\n+\tLow-level Commands / Interrogators\n+\n+\tLow-level Commands / Syncing Repositories\n+\n+\tLow-level Commands / Internal Helpers\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success \"'git help -g' section spacing\" '\n \ttest_section_spacing_trailer git help -g <<-\\EOF &&\n \n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445105","messageId":"patch-7.7-08fd12fe7b4-20211228T153456Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH 7/7] help: don't print \"\\n\" before single-section output","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-28T15:35:12Z","receivedAt":"2021-12-28T15:36:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a formatting regression in 1b81d8cb19d (help: use command-list.txt\nfor the source of guides, 2018-05-20). Adjust the output of \"git help\n--guides\" and any other future single-section commands so that a\nnewline isn't inserted before the only section being printed.\n\nThis changes the output from:\n\n    $ git help --guides\n\n    The Git concept guides are:\n    [...]\n\nTo:\n\n    $ git help --guides\n    The Git concept guides are:\n    [...]\n\nThat we started printing an extra \"\\n\" in 1b81d8cb19d wasn't intended,\nbut an emergent effect of moving all of the printing of \"git help\"\noutput to code that was ready to handle printing N sections.\n\nWith 1b81d8cb19d we started using the \"print_cmd_by_category()\"\nfunction added earlier in the same series, or in cfb22a02ab5 (help:\nuse command-list.h for common command list, 2018-05-10).\n\nFixing this formatting nit is easy enough. Let's have all of the\noutput that would like to be \"\\n\"-separated from other lines emit its\nown \"\\n\". We then adjust \"print_cmd_by_category()\" to only print a\n\"\\n\" to delimit the sections it's printing out.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c          | 5 ++++-\n t/t0012-help.sh | 1 -\n 2 files changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 2296f06ad9f..30be45cea59 100644\n--- a/help.c\n+++ b/help.c\n@@ -124,7 +124,8 @@ static void print_cmd_by_category(const struct category_description *catdesc,\n \t\tuint32_t mask = catdesc[i].category;\n \t\tconst char *desc = catdesc[i].desc;\n \n-\t\tputchar('\\n');\n+\t\tif (i)\n+\t\t\tputchar('\\n');\n \t\tputs(_(desc));\n \t\tprint_command_list(cmds, mask, longest);\n \t}\n@@ -328,6 +329,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n void list_common_cmds_help(void)\n {\n \tputs(_(\"These are common Git commands used in various situations:\"));\n+\tputchar('\\n');\n \tprint_cmd_by_category(common_categories, NULL);\n }\n \n@@ -481,6 +483,7 @@ void list_all_cmds_help(int show_external_commands, int show_aliases)\n \tint longest;\n \n \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tputchar('\\n');\n \tprint_cmd_by_category(main_categories, &longest);\n \n \tif (show_external_commands)\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex c41b412e34a..aae01f15229 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -223,7 +223,6 @@ test_expect_success \"'git help -a' section spacing\" '\n \n test_expect_success \"'git help -g' section spacing\" '\n \ttest_section_spacing_trailer git help -g <<-\\EOF &&\n-\n \tThe Git concept guides are:\n \n \tEOF\n-- \n2.34.1.1257.g2af47340c7b\n\n"},{"id":"445108","messageId":"CAPig+cSVLPiGUAiK8tt1dp3BVLAwXCAeMvM9LenBUY4s_xBQ+A@mail.gmail.com","threadId":"57159","inReplyTo":"patch-5.7-12ff152bd57-20211228T153456Z-avarab@gmail.com","subject":"Re: [PATCH 5/7] help: error if [-a|-g|-c] and [-i|-m|-w] are combined","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-12-28T16:18:02Z","receivedAt":"2021-12-28T16:18:15Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Dec 28, 2021 at 10:36 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> Add more sanity checking to \"git help\" usage by erroring out if these\n> man viewer options are combined with incompatible command-modes that\n> will never use these documentation viewers.\n>\n> This continues the work started in d35d03cf93e (help: simplify by\n> moving to OPT_CMDMODE(), 2021-09-22) of adding more sanity checking to\n> \"git help\". Doing this allows us to clarify the \"SYNOPSIS\" in the\n> documentation, and the \"git help -h\" output.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n> diff --git a/builtin/help.c b/builtin/help.c\n> @@ -581,6 +581,13 @@ static void no_extra_argc(int argc)\n> +static void no_format(void)\n> +{\n> +       if (help_format != HELP_FORMAT_NONE)\n> +               usage_msg_opt(_(\"[-a|--all] cannot be combined with [[-i|--info] [-m|--man] [-w|--web]]\"),\n> +                             builtin_help_usage, builtin_help_options);\n> +}\n\nNit: The square brackets in the message may be unnecessarily\nconfusing. (Indeed, what exactly do they mean in this context?) Also,\nthe short options may not add much value: the user who typed `-w`\nknows presumably that it is shorthand for `--web`. So, one\nsimplification would be:\n\n    '--all' cannot be combined with '--info', '--man', or '--web'\n"},{"id":"445110","messageId":"CAPig+cR4B6+-zw2RAgkU6c5miDxyo5PP_dmqqp+6xpSGt=9obg@mail.gmail.com","threadId":"57159","inReplyTo":"patch-6.7-a5ef9f69530-20211228T153456Z-avarab@gmail.com","subject":"Re: [PATCH 6/7] help: add --no-[external-commands|aliases] for use with --all","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-12-28T16:28:15Z","receivedAt":"2021-12-28T16:28:27Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Dec 28, 2021 at 10:36 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> Add the ability to only emit git's own usage information under\n> --all. This also allows us to extend the \"test_section_spacing\" tests\n> added in a preceding commit to test \"git help --all\"\n> output.\n>\n> Previously we could not do that, as the tests might find a git-*\n> command in the \"$PATH\", which would make the output differ from one\n> setup to another.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n> diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\n> @@ -8,7 +8,7 @@ git-help - Display help information about Git\n> -'git help' [-a|--all] [--[no-]verbose]\n> +'git help' [-a|--all] [--[no-]verbose] [--[no-](external-commands|aliases)]\n\nAre these two new options mutually exclusive as this synopsis line\nseems to indicate? Glancing at the code, it looks like they can be\nused together. So, perhaps the synopsis should just say:\n\n    'git help' [-a|--all] [--[no-]verbose] [--[no-]external-commands]\n[--[no-]aliases]\n\n> diff --git a/builtin/help.c b/builtin/help.c\n> @@ -51,9 +51,14 @@ static const char *html_path;\n>         OPT_CMDMODE('a', \"all\", &cmd_mode, N_(\"print all available commands\"),\n>                     HELP_ACTION_ALL),\n> +       OPT_BOOL(0, \"external-commands\", &show_external_commands,\n> +                N_(\"show external commands in --all?\")),\n> +       OPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all?\")),\n>         OPT_HIDDEN_BOOL(0, \"exclude-guides\", &exclude_guides, N_(\"exclude guides\")),\n\nNit: I don't see question marks on any of the existing options. It's\nnot clear what purpose they serve here.\n\n> @@ -75,7 +80,7 @@ static struct option builtin_help_options[] = {\n>  static const char * const builtin_help_usage[] = {\n> -       N_(\"git help [-a|--all] [--[no-]verbose]]\"),\n> +       N_(\"git help [-a|--all] [--[no-]verbose]] [--[no-](external-commands|aliases)]\"),\n\nSame observation made above about mutual exclusion.\n"},{"id":"445157","messageId":"211229.86v8z8gtt4.gmgdl@evledraar.gmail.com","threadId":"57159","inReplyTo":"CAPig+cSVLPiGUAiK8tt1dp3BVLAwXCAeMvM9LenBUY4s_xBQ+A@mail.gmail.com","subject":"Re: [PATCH 5/7] help: error if [-a|-g|-c] and [-i|-m|-w] are combined","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-12-29T00:04:35Z","receivedAt":"2021-12-29T00:04:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Dec 28 2021, Eric Sunshine wrote:\n\n> On Tue, Dec 28, 2021 at 10:36 AM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> Add more sanity checking to \"git help\" usage by erroring out if these\n>> man viewer options are combined with incompatible command-modes that\n>> will never use these documentation viewers.\n>>\n>> This continues the work started in d35d03cf93e (help: simplify by\n>> moving to OPT_CMDMODE(), 2021-09-22) of adding more sanity checking to\n>> \"git help\". Doing this allows us to clarify the \"SYNOPSIS\" in the\n>> documentation, and the \"git help -h\" output.\n>>\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>> diff --git a/builtin/help.c b/builtin/help.c\n>> @@ -581,6 +581,13 @@ static void no_extra_argc(int argc)\n>> +static void no_format(void)\n>> +{\n>> +       if (help_format != HELP_FORMAT_NONE)\n>> +               usage_msg_opt(_(\"[-a|--all] cannot be combined with [[-i|--info] [-m|--man] [-w|--web]]\"),\n>> +                             builtin_help_usage, builtin_help_options);\n>> +}\n>\n> Nit: The square brackets in the message may be unnecessarily\n> confusing. (Indeed, what exactly do they mean in this context?) Also,\n> the short options may not add much value: the user who typed `-w`\n> knows presumably that it is shorthand for `--web`. So, one\n> simplification would be:\n>\n>     '--all' cannot be combined with '--info', '--man', or '--web'\n\nThanks, will change it.\n"},{"id":"449044","messageId":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com","subject":"[PATCH v2 0/9] help: tests, parse_options() sanity, fix \"help -g\" regression","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:43Z","receivedAt":"2022-02-21T19:39:07Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"A late re-roll of [1] which addresses all the comments Eric Sunshine\nraised, thanks for the review, and sorry the v2 took so long!\n\nAs the range-diff shows the main change is a mid-series set of changes\nto sanity check more \"git help <opts>\" incompaitibilities. The\nSYNOPSIS issues etc. Eric noted have also been fixed.\n\n1. https://lore.kernel.org/git/cover-0.7-00000000000-20211228T153456Z-avarab@gmail.com/\n\nÆvar Arnfjörð Bjarmason (9):\n  help doc: add missing \"]\" to \"[-a|--all]\"\n  help.c: use puts() instead of printf{,_ln}() for consistency\n  help tests: test \"git\" and \"git help [-a|-g] spacing\n  help.c: split up list_all_cmds_help() function\n  help: note the option name on option incompatibility\n  help: correct usage & behavior of \"git help --all\"\n  help: error if [-a|-g|-c] and [-i|-m|-w] are combined\n  help: add --no-[external-commands|aliases] for use with --all\n  help: don't print \"\\n\" before single-section output\n\n Documentation/git-help.txt | 15 ++++--\n builtin/help.c             | 63 +++++++++++++++++++++----\n help.c                     | 37 +++++++++++----\n help.h                     |  2 +-\n t/t0012-help.sh            | 94 ++++++++++++++++++++++++++++++++++++++\n 5 files changed, 187 insertions(+), 24 deletions(-)\n\nRange-diff against v1:\n 1:  652dae26bf4 =  1:  c4b66c36c17 help doc: add missing \"]\" to \"[-a|--all]\"\n 2:  f84662469a3 =  2:  124643c4b35 help.c: use puts() instead of printf{,_ln}() for consistency\n 3:  3956937cf3b !  3:  3e39116f197 help tests: test \"git\" and \"git help [-a|-g] spacing\n    @@ t/t0012-help.sh: test_expect_success 'git help --config-sections-for-completion'\n     +'\n     +\n      test_expect_success 'generate builtin list' '\n    + \tmkdir -p sub &&\n      \tgit --list-cmds=builtins >builtins\n    - '\n 4:  f040dd549b4 =  4:  f9c4d5e2d28 help.c: split up list_all_cmds_help() function\n 5:  12ff152bd57 <  -:  ----------- help: error if [-a|-g|-c] and [-i|-m|-w] are combined\n -:  ----------- >  5:  e5c49089106 help: note the option name on option incompatibility\n -:  ----------- >  6:  868e8a6cf83 help: correct usage & behavior of \"git help --all\"\n -:  ----------- >  7:  992ee6580ac help: error if [-a|-g|-c] and [-i|-m|-w] are combined\n 6:  a5ef9f69530 !  8:  c81c0cbbcdb help: add --no-[external-commands|aliases] for use with --all\n    @@ Documentation/git-help.txt: git-help - Display help information about Git\n      --------\n      [verse]\n     -'git help' [-a|--all] [--[no-]verbose]\n    -+'git help' [-a|--all] [--[no-]verbose] [--[no-](external-commands|aliases)]\n    ++'git help' [-a|--all] [--[no-]verbose] [--[no-]external-commands] [--[no-]aliases]\n      'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n      'git help' [-g|--guides]\n      'git help' [-c|--config]\n     @@ Documentation/git-help.txt: OPTIONS\n    - \tPrints all the available commands on the standard output. This\n    - \toption overrides any given command or guide name.\n    + --all::\n    + \tPrints all the available commands on the standard output.\n      \n     +--no-external-commands::\n     +\tWhen used with `--all`, exclude the listing of external \"git-*\"\n    @@ builtin/help.c: static const char *html_path;\n      \tOPT_CMDMODE('a', \"all\", &cmd_mode, N_(\"print all available commands\"),\n      \t\t    HELP_ACTION_ALL),\n     +\tOPT_BOOL(0, \"external-commands\", &show_external_commands,\n    -+\t\t N_(\"show external commands in --all?\")),\n    -+\tOPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all?\")),\n    ++\t\t N_(\"show external commands in --all\")),\n    ++\tOPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all\")),\n      \tOPT_HIDDEN_BOOL(0, \"exclude-guides\", &exclude_guides, N_(\"exclude guides\")),\n      \tOPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), HELP_FORMAT_MAN),\n      \tOPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web browser\"),\n    @@ builtin/help.c: static struct option builtin_help_options[] = {\n      \n      static const char * const builtin_help_usage[] = {\n     -\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n    -+\tN_(\"git help [-a|--all] [--[no-]verbose]] [--[no-](external-commands|aliases)]\"),\n    ++\tN_(\"git help [-a|--all] [--[no-]verbose]] [--[no-]external-commands] [--[no-]aliases]\"),\n      \tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n      \tN_(\"git help [-g|--guides]\"),\n      \tN_(\"git help [-c|--config]\"),\n    @@ builtin/help.c: int cmd_help(int argc, const char **argv, const char *prefix)\n     +\n      \tswitch (cmd_mode) {\n      \tcase HELP_ACTION_ALL:\n    - \t\tno_format();\n    + \t\topt_mode_usage(argc, \"--all\", help_format);\n      \t\tif (verbose) {\n      \t\t\tsetup_pager();\n     -\t\t\tlist_all_cmds_help();\n 7:  08fd12fe7b4 =  9:  08dc693dc3e help: don't print \"\\n\" before single-section output\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449045","messageId":"patch-v2-1.9-c4b66c36c17-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 1/9] help doc: add missing \"]\" to \"[-a|--all]\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:44Z","receivedAt":"2022-02-21T19:39:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a missing \"]\" to documentation added in 63eae83f8f3 (help: add \"-a\n--verbose\" to list all commands with synopsis, 2018-05-20). This made\nit seem as though \"--[no-]verbose\" can only be provided with \"--all\",\nnot \"-a\". The corresponding usage information in the C\ncode (\"builtin_help_usage\") does not have the same problem.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex 44ea63cc6d3..cf1d53e9499 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -8,7 +8,7 @@ git-help - Display help information about Git\n SYNOPSIS\n --------\n [verse]\n-'git help' [-a|--all [--[no-]verbose]]\n+'git help' [-a|--all] [--[no-]verbose]\n \t   [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449046","messageId":"patch-v2-2.9-124643c4b35-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 2/9] help.c: use puts() instead of printf{,_ln}() for consistency","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:45Z","receivedAt":"2022-02-21T19:39:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change code in \"help.c\" that used printf_ln() without format\nspecifiers to use puts() instead, as other existing code in the file\ndoes. Let's also change related code to use puts() instead of the\nequivalent of calling \"printf\" with a \"%s\\n\" format.\n\nThis formatting-only change will make a subsequent functional change\neasier to read, as it'll be changing code that's consistently using\nthe same functions to do the same things.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 71444906ddf..77af953826e 100644\n--- a/help.c\n+++ b/help.c\n@@ -124,7 +124,8 @@ static void print_cmd_by_category(const struct category_description *catdesc,\n \t\tuint32_t mask = catdesc[i].category;\n \t\tconst char *desc = catdesc[i].desc;\n \n-\t\tprintf(\"\\n%s\\n\", _(desc));\n+\t\tputchar('\\n');\n+\t\tputs(_(desc));\n \t\tprint_command_list(cmds, mask, longest);\n \t}\n \tfree(cmds);\n@@ -317,7 +318,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n \t}\n \n \tif (other_cmds->cnt) {\n-\t\tprintf_ln(_(\"git commands available from elsewhere on your $PATH\"));\n+\t\tputs(_(\"git commands available from elsewhere on your $PATH\"));\n \t\tputchar('\\n');\n \t\tpretty_print_cmdnames(other_cmds, colopts);\n \t\tputchar('\\n');\n@@ -439,7 +440,7 @@ void list_all_cmds_help(void)\n \tstruct cmdname_help *aliases;\n \tint i, longest;\n \n-\tprintf_ln(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n \tprint_cmd_by_category(main_categories, &longest);\n \n \tlist_all_other_cmds(&others);\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449047","messageId":"patch-v2-3.9-3e39116f197-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 3/9] help tests: test \"git\" and \"git help [-a|-g] spacing","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:46Z","receivedAt":"2022-02-21T19:39:27Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"There's logic in \"help.c\"'s \"print_cmd_by_category()\" to emit \"help\"\noutput with particular spacing, which doesn't make much sense when\nemitting only one section with \"help -g\".\n\nLet's add tests for the current spacing in preparation for a\nsubsequent whitespace formatting fix, and make sure that that fix\ndoesn't cause regressions for the \"git\" and \"git help\" output.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0012-help.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 45 insertions(+)\n\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex cbd725ccac8..9ac3f5d3c4b 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -138,6 +138,51 @@ test_expect_success 'git help --config-sections-for-completion' '\n \ttest_cmp human.munged sections\n '\n \n+test_section_spacing () {\n+\tcat >expect &&\n+\t\"$@\" >out &&\n+\tgrep -E \"(^[^ ]|^$)\" out >actual\n+}\n+\n+test_section_spacing_trailer () {\n+\ttest_section_spacing \"$@\" &&\n+\ttest_expect_code 1 git >out &&\n+\tsed -n '/list available subcommands/,$p' <out >>expect\n+}\n+\n+\n+for cmd in git \"git help\"\n+do\n+\ttest_expect_success \"'$cmd' section spacing\" '\n+\t\ttest_section_spacing_trailer git help <<-\\EOF &&\n+\t\tusage: git [--version] [--help] [-C <path>] [-c <name>=<value>]\n+\n+\t\tThese are common Git commands used in various situations:\n+\n+\t\tstart a working area (see also: git help tutorial)\n+\n+\t\twork on the current change (see also: git help everyday)\n+\n+\t\texamine the history and state (see also: git help revisions)\n+\n+\t\tgrow, mark and tweak your common history\n+\n+\t\tcollaborate (see also: git help workflows)\n+\n+\t\tEOF\n+\t\ttest_cmp expect actual\n+\t'\n+done\n+\n+test_expect_success \"'git help -g' section spacing\" '\n+\ttest_section_spacing_trailer git help -g <<-\\EOF &&\n+\n+\tThe Git concept guides are:\n+\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'generate builtin list' '\n \tmkdir -p sub &&\n \tgit --list-cmds=builtins >builtins\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449048","messageId":"patch-v2-6.9-868e8a6cf83-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 6/9] help: correct usage & behavior of \"git help --all\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:49Z","receivedAt":"2022-02-21T19:39:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Do the same for the \"--all\" option that I did for \"--guides\" in\n9856ea6785c (help: correct usage & behavior of \"git help --guides\",\n2021-09-22). I.e. we've documented it as ignoring non-option\narguments, let's have it error out instead.\n\nAs with other changes made in 62f035aee3f (Merge branch\n'ab/help-config-vars', 2021-10-13) this is technically a change in\nbehavior, but in practice it's just a bug fix. We were ignoring this\nbefore, but by erroring we can simplify our documentation and\nsynopsis, as well as avoid user confusion as they wonder what the\ndifference between e.g. \"git help --all\" and \"git help --all status\"\nis (there wasn't any difference).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt | 5 ++---\n builtin/help.c             | 5 +++--\n t/t0012-help.sh            | 3 +++\n 3 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex cf1d53e9499..d07590c8ff7 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git help' [-a|--all] [--[no-]verbose]\n-\t   [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n+'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n \n@@ -46,8 +46,7 @@ OPTIONS\n -------\n -a::\n --all::\n-\tPrints all the available commands on the standard output. This\n-\toption overrides any given command or guide name.\n+\tPrints all the available commands on the standard output.\n \n --verbose::\n \tWhen used with `--all` print description for all recognized\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 1c1581ef850..b682446bbf5 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -75,8 +75,8 @@ static struct option builtin_help_options[] = {\n };\n \n static const char * const builtin_help_usage[] = {\n-\tN_(\"git help [-a|--all] [--[no-]verbose]]\\n\"\n-\t   \"         [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n+\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n+\tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n \tN_(\"git help [-g|--guides]\"),\n \tN_(\"git help [-c|--config]\"),\n \tNULL\n@@ -594,6 +594,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \n \tswitch (cmd_mode) {\n \tcase HELP_ACTION_ALL:\n+\t\topt_mode_usage(argc, \"--all\");\n \t\tif (verbose) {\n \t\t\tsetup_pager();\n \t\t\tlist_all_cmds_help();\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex 9ac3f5d3c4b..c87730aa920 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -35,6 +35,9 @@ test_expect_success 'basic help commands' '\n '\n \n test_expect_success 'invalid usage' '\n+\ttest_expect_code 129 git help -a add &&\n+\ttest_expect_code 129 git help --all add &&\n+\n \ttest_expect_code 129 git help -g add &&\n \ttest_expect_code 129 git help -a -c &&\n \n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449049","messageId":"patch-v2-4.9-f9c4d5e2d28-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 4/9] help.c: split up list_all_cmds_help() function","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:47Z","receivedAt":"2022-02-21T19:39:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Split up the listing of commands and aliases from\nlist_all_cmds_help(). This will make a subsequent functional change\nsmaller.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c | 27 ++++++++++++++++++++-------\n 1 file changed, 20 insertions(+), 7 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 77af953826e..004117347ee 100644\n--- a/help.c\n+++ b/help.c\n@@ -433,15 +433,10 @@ static int get_alias(const char *var, const char *value, void *data)\n \treturn 0;\n }\n \n-void list_all_cmds_help(void)\n+static void list_all_cmds_help_external_commands(void)\n {\n \tstruct string_list others = STRING_LIST_INIT_DUP;\n-\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n-\tstruct cmdname_help *aliases;\n-\tint i, longest;\n-\n-\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n-\tprint_cmd_by_category(main_categories, &longest);\n+\tint i;\n \n \tlist_all_other_cmds(&others);\n \tif (others.nr)\n@@ -449,6 +444,13 @@ void list_all_cmds_help(void)\n \tfor (i = 0; i < others.nr; i++)\n \t\tprintf(\"   %s\\n\", others.items[i].string);\n \tstring_list_clear(&others, 0);\n+}\n+\n+static void list_all_cmds_help_aliases(int longest)\n+{\n+\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n+\tstruct cmdname_help *aliases;\n+\tint i;\n \n \tgit_config(get_alias, &alias_list);\n \tstring_list_sort(&alias_list);\n@@ -474,6 +476,17 @@ void list_all_cmds_help(void)\n \tstring_list_clear(&alias_list, 1);\n }\n \n+void list_all_cmds_help(void)\n+{\n+\tint longest;\n+\n+\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tprint_cmd_by_category(main_categories, &longest);\n+\n+\tlist_all_cmds_help_external_commands();\n+\tlist_all_cmds_help_aliases(longest);\n+}\n+\n int is_in_cmdlist(struct cmdnames *c, const char *s)\n {\n \tint i;\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449050","messageId":"patch-v2-7.9-992ee6580ac-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 7/9] help: error if [-a|-g|-c] and [-i|-m|-w] are combined","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:50Z","receivedAt":"2022-02-21T19:39:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add more sanity checking to \"git help\" usage by erroring out if these\nman viewer options are combined with incompatible command-modes that\nwill never use these documentation viewers.\n\nThis continues the work started in d35d03cf93e (help: simplify by\nmoving to OPT_CMDMODE(), 2021-09-22) of adding more sanity checking to\n\"git help\". Doing this allows us to clarify the \"SYNOPSIS\" in the\ndocumentation, and the \"git help -h\" output.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/help.c  | 41 +++++++++++++++++++++++++++++++++++------\n t/t0012-help.sh | 10 ++++++++++\n 2 files changed, 45 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/help.c b/builtin/help.c\nindex b682446bbf5..1fc45adfcc7 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -574,12 +574,40 @@ static const char *check_git_cmd(const char* cmd)\n \treturn cmd;\n }\n \n-static void opt_mode_usage(int argc, const char *opt_mode)\n+static void no_help_format(const char *opt_mode, enum help_format fmt)\n+{\n+\tconst char *opt_fmt;\n+\n+\tswitch (fmt) {\n+\tcase HELP_FORMAT_NONE:\n+\t\treturn;\n+\tcase HELP_FORMAT_MAN:\n+\t\topt_fmt = \"--man\";\n+\t\tbreak;\n+\tcase HELP_FORMAT_INFO:\n+\t\topt_fmt = \"--info\";\n+\t\tbreak;\n+\tcase HELP_FORMAT_WEB:\n+\t\topt_fmt = \"--web\";\n+\t\tbreak;\n+\tdefault:\n+\t\tBUG(\"unreachable\");\n+\t}\n+\n+\tusage_msg_optf(_(\"options '%s' and '%s' cannot be used together\"),\n+\t\t       builtin_help_usage, builtin_help_options, opt_mode,\n+\t\t       opt_fmt);\n+}\n+\n+static void opt_mode_usage(int argc, const char *opt_mode,\n+\t\t\t   enum help_format fmt)\n {\n \tif (argc)\n \t\tusage_msg_optf(_(\"the '%s' option doesn't take any non-option arguments\"),\n \t\t\t       builtin_help_usage, builtin_help_options,\n \t\t\t       opt_mode);\n+\n+\tno_help_format(opt_mode, fmt);\n }\n \n int cmd_help(int argc, const char **argv, const char *prefix)\n@@ -594,7 +622,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \n \tswitch (cmd_mode) {\n \tcase HELP_ACTION_ALL:\n-\t\topt_mode_usage(argc, \"--all\");\n+\t\topt_mode_usage(argc, \"--all\", help_format);\n \t\tif (verbose) {\n \t\t\tsetup_pager();\n \t\t\tlist_all_cmds_help();\n@@ -606,20 +634,21 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\tbreak;\n \tcase HELP_ACTION_GUIDES:\n-\t\topt_mode_usage(argc, \"--guides\");\n+\t\topt_mode_usage(argc, \"--guides\", help_format);\n \t\tlist_guides_help();\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_FOR_COMPLETION:\n-\t\topt_mode_usage(argc, \"--config-for-completion\");\n+\t\topt_mode_usage(argc, \"--config-for-completion\", help_format);\n \t\tlist_config_help(SHOW_CONFIG_VARS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:\n-\t\topt_mode_usage(argc, \"--config-sections-for-completion\");\n+\t\topt_mode_usage(argc, \"--config-sections-for-completion\",\n+\t\t\t       help_format);\n \t\tlist_config_help(SHOW_CONFIG_SECTIONS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG:\n-\t\topt_mode_usage(argc, \"--config\");\n+\t\topt_mode_usage(argc, \"--config\", help_format);\n \t\tsetup_pager();\n \t\tlist_config_help(SHOW_CONFIG_HUMAN);\n \t\tprintf(\"\\n%s\\n\", _(\"'git help config' for more information\"));\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex c87730aa920..f12783fd153 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -49,6 +49,16 @@ test_expect_success 'invalid usage' '\n \ttest_expect_code 129 git help --config-sections-for-completion add\n '\n \n+for opt in '-a' '-g' '-c' '--config-for-completion' '--config-sections-for-completion'\n+do\n+\ttest_expect_success \"invalid usage of '$opt' with [-i|-m|-w]\" '\n+\t\tgit help $opt &&\n+\t\ttest_expect_code 129 git help $opt -i &&\n+\t\ttest_expect_code 129 git help $opt -m &&\n+\t\ttest_expect_code 129 git help $opt -w\n+\t'\n+done\n+\n test_expect_success \"works for commands and guides by default\" '\n \tconfigure_help &&\n \tgit help status &&\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449051","messageId":"patch-v2-9.9-08dc693dc3e-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 9/9] help: don't print \"\\n\" before single-section output","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:52Z","receivedAt":"2022-02-21T19:39:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a formatting regression in 1b81d8cb19d (help: use command-list.txt\nfor the source of guides, 2018-05-20). Adjust the output of \"git help\n--guides\" and any other future single-section commands so that a\nnewline isn't inserted before the only section being printed.\n\nThis changes the output from:\n\n    $ git help --guides\n\n    The Git concept guides are:\n    [...]\n\nTo:\n\n    $ git help --guides\n    The Git concept guides are:\n    [...]\n\nThat we started printing an extra \"\\n\" in 1b81d8cb19d wasn't intended,\nbut an emergent effect of moving all of the printing of \"git help\"\noutput to code that was ready to handle printing N sections.\n\nWith 1b81d8cb19d we started using the \"print_cmd_by_category()\"\nfunction added earlier in the same series, or in cfb22a02ab5 (help:\nuse command-list.h for common command list, 2018-05-10).\n\nFixing this formatting nit is easy enough. Let's have all of the\noutput that would like to be \"\\n\"-separated from other lines emit its\nown \"\\n\". We then adjust \"print_cmd_by_category()\" to only print a\n\"\\n\" to delimit the sections it's printing out.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n help.c          | 5 ++++-\n t/t0012-help.sh | 1 -\n 2 files changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/help.c b/help.c\nindex 45a21e7e35c..afd3af24124 100644\n--- a/help.c\n+++ b/help.c\n@@ -124,7 +124,8 @@ static void print_cmd_by_category(const struct category_description *catdesc,\n \t\tuint32_t mask = catdesc[i].category;\n \t\tconst char *desc = catdesc[i].desc;\n \n-\t\tputchar('\\n');\n+\t\tif (i)\n+\t\t\tputchar('\\n');\n \t\tputs(_(desc));\n \t\tprint_command_list(cmds, mask, longest);\n \t}\n@@ -328,6 +329,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n void list_common_cmds_help(void)\n {\n \tputs(_(\"These are common Git commands used in various situations:\"));\n+\tputchar('\\n');\n \tprint_cmd_by_category(common_categories, NULL);\n }\n \n@@ -481,6 +483,7 @@ void list_all_cmds_help(int show_external_commands, int show_aliases)\n \tint longest;\n \n \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n+\tputchar('\\n');\n \tprint_cmd_by_category(main_categories, &longest);\n \n \tif (show_external_commands)\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex 64321480c68..6c3e1f7159d 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -226,7 +226,6 @@ test_expect_success \"'git help -a' section spacing\" '\n \n test_expect_success \"'git help -g' section spacing\" '\n \ttest_section_spacing_trailer git help -g <<-\\EOF &&\n-\n \tThe Git concept guides are:\n \n \tEOF\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449052","messageId":"patch-v2-8.9-c81c0cbbcdb-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 8/9] help: add --no-[external-commands|aliases] for use with --all","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:51Z","receivedAt":"2022-02-21T19:39:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add the ability to only emit git's own usage information under\n--all. This also allows us to extend the \"test_section_spacing\" tests\nadded in a preceding commit to test \"git help --all\"\noutput.\n\nPreviously we could not do that, as the tests might find a git-*\ncommand in the \"$PATH\", which would make the output differ from one\nsetup to another.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-help.txt | 10 +++++++++-\n builtin/help.c             | 16 ++++++++++++++--\n help.c                     |  8 +++++---\n help.h                     |  2 +-\n t/t0012-help.sh            | 37 +++++++++++++++++++++++++++++++++++++\n 5 files changed, 66 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex d07590c8ff7..239c68db457 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -8,7 +8,7 @@ git-help - Display help information about Git\n SYNOPSIS\n --------\n [verse]\n-'git help' [-a|--all] [--[no-]verbose]\n+'git help' [-a|--all] [--[no-]verbose] [--[no-]external-commands] [--[no-]aliases]\n 'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n 'git help' [-g|--guides]\n 'git help' [-c|--config]\n@@ -48,6 +48,14 @@ OPTIONS\n --all::\n \tPrints all the available commands on the standard output.\n \n+--no-external-commands::\n+\tWhen used with `--all`, exclude the listing of external \"git-*\"\n+\tcommands found in the `$PATH`.\n+\n+--no-aliases::\n+\tWhen used with `--all`, exclude the listing of configured\n+\taliases.\n+\n --verbose::\n \tWhen used with `--all` print description for all recognized\n \tcommands. This is the default.\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 1fc45adfcc7..01eda326c31 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -51,9 +51,14 @@ static const char *html_path;\n static int verbose = 1;\n static enum help_format help_format = HELP_FORMAT_NONE;\n static int exclude_guides;\n+static int show_external_commands = -1;\n+static int show_aliases = -1;\n static struct option builtin_help_options[] = {\n \tOPT_CMDMODE('a', \"all\", &cmd_mode, N_(\"print all available commands\"),\n \t\t    HELP_ACTION_ALL),\n+\tOPT_BOOL(0, \"external-commands\", &show_external_commands,\n+\t\t N_(\"show external commands in --all\")),\n+\tOPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all\")),\n \tOPT_HIDDEN_BOOL(0, \"exclude-guides\", &exclude_guides, N_(\"exclude guides\")),\n \tOPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), HELP_FORMAT_MAN),\n \tOPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web browser\"),\n@@ -75,7 +80,7 @@ static struct option builtin_help_options[] = {\n };\n \n static const char * const builtin_help_usage[] = {\n-\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n+\tN_(\"git help [-a|--all] [--[no-]verbose]] [--[no-]external-commands] [--[no-]aliases]\"),\n \tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n \tN_(\"git help [-g|--guides]\"),\n \tN_(\"git help [-c|--config]\"),\n@@ -620,12 +625,19 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \t\t\tbuiltin_help_usage, 0);\n \tparsed_help_format = help_format;\n \n+\tif (cmd_mode != HELP_ACTION_ALL &&\n+\t    (show_external_commands >= 0 ||\n+\t     show_aliases >= 0))\n+\t\tusage_msg_opt(_(\"the '--no-[external-commands|aliases]' options can only be used with '--all'\"),\n+\t\t\t      builtin_help_usage, builtin_help_options);\n+\n \tswitch (cmd_mode) {\n \tcase HELP_ACTION_ALL:\n \t\topt_mode_usage(argc, \"--all\", help_format);\n \t\tif (verbose) {\n \t\t\tsetup_pager();\n-\t\t\tlist_all_cmds_help();\n+\t\t\tlist_all_cmds_help(show_external_commands,\n+\t\t\t\t\t   show_aliases);\n \t\t\treturn 0;\n \t\t}\n \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\ndiff --git a/help.c b/help.c\nindex 004117347ee..45a21e7e35c 100644\n--- a/help.c\n+++ b/help.c\n@@ -476,15 +476,17 @@ static void list_all_cmds_help_aliases(int longest)\n \tstring_list_clear(&alias_list, 1);\n }\n \n-void list_all_cmds_help(void)\n+void list_all_cmds_help(int show_external_commands, int show_aliases)\n {\n \tint longest;\n \n \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n \tprint_cmd_by_category(main_categories, &longest);\n \n-\tlist_all_cmds_help_external_commands();\n-\tlist_all_cmds_help_aliases(longest);\n+\tif (show_external_commands)\n+\t\tlist_all_cmds_help_external_commands();\n+\tif (show_aliases)\n+\t\tlist_all_cmds_help_aliases(longest);\n }\n \n int is_in_cmdlist(struct cmdnames *c, const char *s)\ndiff --git a/help.h b/help.h\nindex 9d383f1a0b2..971a3ad855a 100644\n--- a/help.h\n+++ b/help.h\n@@ -20,7 +20,7 @@ static inline void mput_char(char c, unsigned int num)\n }\n \n void list_common_cmds_help(void);\n-void list_all_cmds_help(void);\n+void list_all_cmds_help(int show_external_commands, int show_aliases);\n void list_guides_help(void);\n \n void list_all_main_cmds(struct string_list *list);\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex f12783fd153..64321480c68 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -57,6 +57,19 @@ do\n \t\ttest_expect_code 129 git help $opt -m &&\n \t\ttest_expect_code 129 git help $opt -w\n \t'\n+\n+\tif test \"$opt\" = \"-a\"\n+\tthen\n+\t\tcontinue\n+\tfi\n+\n+\ttest_expect_success \"invalid usage of '$opt' with --no-external-commands\" '\n+\t\ttest_expect_code 129 git help $opt --no-external-commands\n+\t'\n+\n+\ttest_expect_success \"invalid usage of '$opt' with --no-aliases\" '\n+\t\ttest_expect_code 129 git help $opt --no-external-commands\n+\t'\n done\n \n test_expect_success \"works for commands and guides by default\" '\n@@ -187,6 +200,30 @@ do\n \t'\n done\n \n+test_expect_success \"'git help -a' section spacing\" '\n+\ttest_section_spacing \\\n+\t\tgit help -a --no-external-commands --no-aliases <<-\\EOF &&\n+\tSee '\\''git help <command>'\\'' to read about a specific subcommand\n+\n+\tMain Porcelain Commands\n+\n+\tAncillary Commands / Manipulators\n+\n+\tAncillary Commands / Interrogators\n+\n+\tInteracting with Others\n+\n+\tLow-level Commands / Manipulators\n+\n+\tLow-level Commands / Interrogators\n+\n+\tLow-level Commands / Syncing Repositories\n+\n+\tLow-level Commands / Internal Helpers\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success \"'git help -g' section spacing\" '\n \ttest_section_spacing_trailer git help -g <<-\\EOF &&\n \n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449053","messageId":"patch-v2-5.9-e5c49089106-20220221T193708Z-avarab@gmail.com","threadId":"57159","inReplyTo":"cover-v2-0.9-00000000000-20220221T193708Z-avarab@gmail.com","subject":"[PATCH v2 5/9] help: note the option name on option incompatibility","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-21T19:38:48Z","receivedAt":"2022-02-21T19:39:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the errors added in d35d03cf93e (help: simplify by moving to\nOPT_CMDMODE(), 2021-09-22) to quote the offending option at the user\nwhen invoked as e.g.:\n\n    git help --guides garbage\n\nNow instead of:\n\n    fatal: this option doesn't take any other arguments\n\nWe'll emit:\n\n    fatal: the '--guides' option doesn't take any non-option arguments\n\nLet's also rename the function, as it will be extended to do other\nchecks that aren't \"no extra argc\" in a subsequent commit.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/help.c | 15 ++++++++-------\n 1 file changed, 8 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/help.c b/builtin/help.c\nindex d387131dd83..1c1581ef850 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -574,11 +574,12 @@ static const char *check_git_cmd(const char* cmd)\n \treturn cmd;\n }\n \n-static void no_extra_argc(int argc)\n+static void opt_mode_usage(int argc, const char *opt_mode)\n {\n \tif (argc)\n-\t\tusage_msg_opt(_(\"this option doesn't take any other arguments\"),\n-\t\t\t      builtin_help_usage, builtin_help_options);\n+\t\tusage_msg_optf(_(\"the '%s' option doesn't take any non-option arguments\"),\n+\t\t\t       builtin_help_usage, builtin_help_options,\n+\t\t\t       opt_mode);\n }\n \n int cmd_help(int argc, const char **argv, const char *prefix)\n@@ -604,20 +605,20 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\tbreak;\n \tcase HELP_ACTION_GUIDES:\n-\t\tno_extra_argc(argc);\n+\t\topt_mode_usage(argc, \"--guides\");\n \t\tlist_guides_help();\n \t\tprintf(\"%s\\n\", _(git_more_info_string));\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_FOR_COMPLETION:\n-\t\tno_extra_argc(argc);\n+\t\topt_mode_usage(argc, \"--config-for-completion\");\n \t\tlist_config_help(SHOW_CONFIG_VARS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:\n-\t\tno_extra_argc(argc);\n+\t\topt_mode_usage(argc, \"--config-sections-for-completion\");\n \t\tlist_config_help(SHOW_CONFIG_SECTIONS);\n \t\treturn 0;\n \tcase HELP_ACTION_CONFIG:\n-\t\tno_extra_argc(argc);\n+\t\topt_mode_usage(argc, \"--config\");\n \t\tsetup_pager();\n \t\tlist_config_help(SHOW_CONFIG_HUMAN);\n \t\tprintf(\"\\n%s\\n\", _(\"'git help config' for more information\"));\n-- \n2.35.1.1132.ga1fe46f8690\n\n"},{"id":"449351","messageId":"xmqqfso9s14j.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-2.9-124643c4b35-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 2/9] help.c: use puts() instead of printf{,_ln}() for consistency","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T21:51:08Z","receivedAt":"2022-02-23T21:51:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> -\t\tprintf(\"\\n%s\\n\", _(desc));\n> +\t\tputchar('\\n');\n> +\t\tputs(_(desc));\n\nThis is sort of \"Meh\".  Even the justification that says \"we'll do\nthe same thing in future patches\" is not really a justification, as\nit is entirely fine to add more of the \"line-break plus %\\n\" printf()\nin the later steps in the same series.\n\n>  \t\tprint_command_list(cmds, mask, longest);\n>  \t}\n>  \tfree(cmds);\n> @@ -317,7 +318,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n>  \t}\n>  \n>  \tif (other_cmds->cnt) {\n> -\t\tprintf_ln(_(\"git commands available from elsewhere on your $PATH\"));\n> +\t\tputs(_(\"git commands available from elsewhere on your $PATH\"));\n\nThis *IS* an improvement, as the first parameter to printf_ln() is\nsupposed to be a format string, and should have been\n\n\tprintf_ln(\"%s\", _(\"git commands ...\"));\n\n> -\tprintf_ln(_(\"See 'git help <command>' to read about a specific subcommand\"));\n> +\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n\nDitto.\n"},{"id":"449353","messageId":"xmqqbkyxs0jz.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-4.9-f9c4d5e2d28-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 4/9] help.c: split up list_all_cmds_help() function","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:03:28Z","receivedAt":"2022-02-23T22:03:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> -void list_all_cmds_help(void)\n> +static void list_all_cmds_help_external_commands(void)\n>  {\n>  \tstruct string_list others = STRING_LIST_INIT_DUP;\n> -\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n> -\tstruct cmdname_help *aliases;\n> -\tint i, longest;\n> -\n> -\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n> -\tprint_cmd_by_category(main_categories, &longest);\n> +\tint i;\n>  \n>  \tlist_all_other_cmds(&others);\n>  \tif (others.nr)\n\nLet's note that in the body of this new helper function, we still\nuse the printf(\"\\n%s\\n\", _(\"group header\")) pattern, not putchar('\\n')\nfollowed by puts().\n\n> @@ -449,6 +444,13 @@ void list_all_cmds_help(void)\n>  \tfor (i = 0; i < others.nr; i++)\n>  \t\tprintf(\"   %s\\n\", others.items[i].string);\n>  \tstring_list_clear(&others, 0);\n> +}\n> +\n> +static void list_all_cmds_help_aliases(int longest)\n> +{\n> +\tstruct string_list alias_list = STRING_LIST_INIT_DUP;\n> +\tstruct cmdname_help *aliases;\n> +\tint i;\n>  \n>  \tgit_config(get_alias, &alias_list);\n>  \tstring_list_sort(&alias_list);\n\nAnd this helper, too.\n\n> @@ -474,6 +476,17 @@ void list_all_cmds_help(void)\n>  \tstring_list_clear(&alias_list, 1);\n>  }\n>  \n> +void list_all_cmds_help(void)\n> +{\n> +\tint longest;\n> +\n> +\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n> +\tprint_cmd_by_category(main_categories, &longest);\n> +\n> +\tlist_all_cmds_help_external_commands();\n> +\tlist_all_cmds_help_aliases(longest);\n> +}\n\nThis does make sense ;-)\n"},{"id":"449354","messageId":"xmqq7d9ls0i6.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-5.9-e5c49089106-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 5/9] help: note the option name on option incompatibility","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:04:33Z","receivedAt":"2022-02-23T22:04:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Change the errors added in d35d03cf93e (help: simplify by moving to\n> OPT_CMDMODE(), 2021-09-22) to quote the offending option at the user\n> when invoked as e.g.:\n>\n>     git help --guides garbage\n>\n> Now instead of:\n>\n>     fatal: this option doesn't take any other arguments\n>\n> We'll emit:\n>\n>     fatal: the '--guides' option doesn't take any non-option arguments\n\nVery good.\n\n> Let's also rename the function, as it will be extended to do other\n> checks that aren't \"no extra argc\" in a subsequent commit.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/help.c | 15 ++++++++-------\n>  1 file changed, 8 insertions(+), 7 deletions(-)\n>\n> diff --git a/builtin/help.c b/builtin/help.c\n> index d387131dd83..1c1581ef850 100644\n> --- a/builtin/help.c\n> +++ b/builtin/help.c\n> @@ -574,11 +574,12 @@ static const char *check_git_cmd(const char* cmd)\n>  \treturn cmd;\n>  }\n>  \n> -static void no_extra_argc(int argc)\n> +static void opt_mode_usage(int argc, const char *opt_mode)\n>  {\n>  \tif (argc)\n> -\t\tusage_msg_opt(_(\"this option doesn't take any other arguments\"),\n> -\t\t\t      builtin_help_usage, builtin_help_options);\n> +\t\tusage_msg_optf(_(\"the '%s' option doesn't take any non-option arguments\"),\n> +\t\t\t       builtin_help_usage, builtin_help_options,\n> +\t\t\t       opt_mode);\n>  }\n>  \n>  int cmd_help(int argc, const char **argv, const char *prefix)\n> @@ -604,20 +605,20 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>  \t\tprintf(\"%s\\n\", _(git_more_info_string));\n>  \t\tbreak;\n>  \tcase HELP_ACTION_GUIDES:\n> -\t\tno_extra_argc(argc);\n> +\t\topt_mode_usage(argc, \"--guides\");\n>  \t\tlist_guides_help();\n>  \t\tprintf(\"%s\\n\", _(git_more_info_string));\n>  \t\treturn 0;\n>  \tcase HELP_ACTION_CONFIG_FOR_COMPLETION:\n> -\t\tno_extra_argc(argc);\n> +\t\topt_mode_usage(argc, \"--config-for-completion\");\n>  \t\tlist_config_help(SHOW_CONFIG_VARS);\n>  \t\treturn 0;\n>  \tcase HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:\n> -\t\tno_extra_argc(argc);\n> +\t\topt_mode_usage(argc, \"--config-sections-for-completion\");\n>  \t\tlist_config_help(SHOW_CONFIG_SECTIONS);\n>  \t\treturn 0;\n>  \tcase HELP_ACTION_CONFIG:\n> -\t\tno_extra_argc(argc);\n> +\t\topt_mode_usage(argc, \"--config\");\n>  \t\tsetup_pager();\n>  \t\tlist_config_help(SHOW_CONFIG_HUMAN);\n>  \t\tprintf(\"\\n%s\\n\", _(\"'git help config' for more information\"));\n"},{"id":"449355","messageId":"220223.86h78pb5nd.gmgdl@evledraar.gmail.com","threadId":"57159","inReplyTo":"xmqqfso9s14j.fsf@gitster.g","subject":"Re: [PATCH v2 2/9] help.c: use puts() instead of printf{,_ln}() for consistency","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-23T21:57:06Z","receivedAt":"2022-02-23T22:05:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Feb 23 2022, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> -\t\tprintf(\"\\n%s\\n\", _(desc));\n>> +\t\tputchar('\\n');\n>> +\t\tputs(_(desc));\n>\n> This is sort of \"Meh\".  Even the justification that says \"we'll do\n> the same thing in future patches\" is not really a justification, as\n> it is entirely fine to add more of the \"line-break plus %\\n\" printf()\n> in the later steps in the same series.\n\nYes, I agree that justification wouldn't make sense, \"let's change this\nfor consistency with code that doesn't exist yet and I'm about to\nintroduce\" is a non-starter as an argument.\n\nBut that's not what I mentioned in the commit message or why I changed\nthis, as noted it's for doing the same \"as other existing code in the\nfile does\".\n\nI.e. you'll see that adjacent and related code if you run this on\nmaster:\n\n    git grep -W '\\\\n' -- help.c\n\nNow, I fully agree that's not a *strong* reason to change this, it could\njust be left in place.\n\nI just thought post-series that skimming through those related functions\nmade for marginally easier reading if they all used the same pattern to\naccomplish the same thing.\n\nIn any case, I don't at all feel strongly about including this change,\nso I can drop it if you'd like. I just wanted to clarify why I changed\nit.\n\n>>  \t\tprint_command_list(cmds, mask, longest);\n>>  \t}\n>>  \tfree(cmds);\n>> @@ -317,7 +318,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n>>  \t}\n>>  \n>>  \tif (other_cmds->cnt) {\n>> -\t\tprintf_ln(_(\"git commands available from elsewhere on your $PATH\"));\n>> +\t\tputs(_(\"git commands available from elsewhere on your $PATH\"));\n>\n> This *IS* an improvement, as the first parameter to printf_ln() is\n> supposed to be a format string, and should have been\n>\n> \tprintf_ln(\"%s\", _(\"git commands ...\"));\n>\n>> -\tprintf_ln(_(\"See 'git help <command>' to read about a specific subcommand\"));\n>> +\tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n>\n> Ditto.\n\n"},{"id":"449356","messageId":"xmqq1qzts04x.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-6.9-868e8a6cf83-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 6/9] help: correct usage & behavior of \"git help --all\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:12:30Z","receivedAt":"2022-02-23T22:12:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\n> index cf1d53e9499..d07590c8ff7 100644\n> --- a/Documentation/git-help.txt\n> +++ b/Documentation/git-help.txt\n> @@ -9,7 +9,7 @@ SYNOPSIS\n>  --------\n>  [verse]\n>  'git help' [-a|--all] [--[no-]verbose]\n> -\t   [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n> +'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>]\n\nHmph, OK.  The earlier one made it appear that when -a is given to\n\"git help\" it would also accept command or guide, which is no longer\ntrue.\n\n>  'git help' [-g|--guides]\n>  'git help' [-c|--config]\n\nThis is not new, but don't we need to fix the mark-up of [-a|--all]\nand [-g|--guides] and [-c|--config]?  It's not like \"We can give 0\nor more of i/-m/-w\".  These are \"we have to give either -a or --all\nto trigger this mode\".\n\n> diff --git a/builtin/help.c b/builtin/help.c\n> index 1c1581ef850..b682446bbf5 100644\n> --- a/builtin/help.c\n> +++ b/builtin/help.c\n> @@ -75,8 +75,8 @@ static struct option builtin_help_options[] = {\n>  };\n>  \n>  static const char * const builtin_help_usage[] = {\n> -\tN_(\"git help [-a|--all] [--[no-]verbose]]\\n\"\n> -\t   \"         [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n> +\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n> +\tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n>  \tN_(\"git help [-g|--guides]\"),\n>  \tN_(\"git help [-c|--config]\"),\n>  \tNULL\n> @@ -594,6 +594,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>  \n>  \tswitch (cmd_mode) {\n>  \tcase HELP_ACTION_ALL:\n> +\t\topt_mode_usage(argc, \"--all\");\n\nOK.\n\n>  \t\tif (verbose) {\n>  \t\t\tsetup_pager();\n>  \t\t\tlist_all_cmds_help();\n> diff --git a/t/t0012-help.sh b/t/t0012-help.sh\n> index 9ac3f5d3c4b..c87730aa920 100755\n> --- a/t/t0012-help.sh\n> +++ b/t/t0012-help.sh\n> @@ -35,6 +35,9 @@ test_expect_success 'basic help commands' '\n>  '\n>  \n>  test_expect_success 'invalid usage' '\n> +\ttest_expect_code 129 git help -a add &&\n> +\ttest_expect_code 129 git help --all add &&\n> +\n>  \ttest_expect_code 129 git help -g add &&\n>  \ttest_expect_code 129 git help -a -c &&\n"},{"id":"449357","messageId":"xmqqv8x5qlea.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-7.9-992ee6580ac-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 7/9] help: error if [-a|-g|-c] and [-i|-m|-w] are combined","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:16:13Z","receivedAt":"2022-02-23T22:16:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Add more sanity checking to \"git help\" usage by erroring out if these\n> man viewer options are combined with incompatible command-modes that\n> will never use these documentation viewers.\n>\n> This continues the work started in d35d03cf93e (help: simplify by\n> moving to OPT_CMDMODE(), 2021-09-22) of adding more sanity checking to\n> \"git help\". Doing this allows us to clarify the \"SYNOPSIS\" in the\n> documentation, and the \"git help -h\" output.\n\nWhile this is not wrong per-se, \"git help --all --web\" in the\nfuture that pops the same information up in your running browser\nwould not be a bad thing to have.\n\nThat use of --web is certainly not in line with --man and --info,\nthough (at that point we'd be saying \"show in browser or show in\nterminal\").\n\nSo I guess this is OK at least for now.\n"},{"id":"449358","messageId":"xmqqo82xql91.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-8.9-c81c0cbbcdb-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 8/9] help: add --no-[external-commands|aliases] for use with --all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:19:22Z","receivedAt":"2022-02-23T22:19:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Add the ability to only emit git's own usage information under\n> --all. This also allows us to extend the \"test_section_spacing\" tests\n> added in a preceding commit to test \"git help --all\"\n> output.\n\nMakes sense.\n\n> +static int show_external_commands = -1;\n> +static int show_aliases = -1;\n>  static struct option builtin_help_options[] = {\n>  \tOPT_CMDMODE('a', \"all\", &cmd_mode, N_(\"print all available commands\"),\n>  \t\t    HELP_ACTION_ALL),\n> +\tOPT_BOOL(0, \"external-commands\", &show_external_commands,\n> +\t\t N_(\"show external commands in --all\")),\n> +\tOPT_BOOL(0, \"aliases\", &show_aliases, N_(\"show aliases in --all\")),\n>  \tOPT_HIDDEN_BOOL(0, \"exclude-guides\", &exclude_guides, N_(\"exclude guides\")),\n>  \tOPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), HELP_FORMAT_MAN),\n>  \tOPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web browser\"),\n> @@ -75,7 +80,7 @@ static struct option builtin_help_options[] = {\n>  };\n>  \n>  static const char * const builtin_help_usage[] = {\n> -\tN_(\"git help [-a|--all] [--[no-]verbose]]\"),\n> +\tN_(\"git help [-a|--all] [--[no-]verbose]] [--[no-]external-commands] [--[no-]aliases]\"),\n>  \tN_(\"git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]\"),\n>  \tN_(\"git help [-g|--guides]\"),\n>  \tN_(\"git help [-c|--config]\"),\n> @@ -620,12 +625,19 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>  \t\t\tbuiltin_help_usage, 0);\n>  \tparsed_help_format = help_format;\n>  \n> +\tif (cmd_mode != HELP_ACTION_ALL &&\n> +\t    (show_external_commands >= 0 ||\n> +\t     show_aliases >= 0))\n> +\t\tusage_msg_opt(_(\"the '--no-[external-commands|aliases]' options can only be used with '--all'\"),\n> +\t\t\t      builtin_help_usage, builtin_help_options);\n\nNice attention to a small detail.\n\n>  \tswitch (cmd_mode) {\n>  \tcase HELP_ACTION_ALL:\n>  \t\topt_mode_usage(argc, \"--all\", help_format);\n>  \t\tif (verbose) {\n>  \t\t\tsetup_pager();\n> -\t\t\tlist_all_cmds_help();\n> +\t\t\tlist_all_cmds_help(show_external_commands,\n> +\t\t\t\t\t   show_aliases);\n>  \t\t\treturn 0;\n>  \t\t}\n>  \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n> diff --git a/help.c b/help.c\n> index 004117347ee..45a21e7e35c 100644\n> --- a/help.c\n> +++ b/help.c\n> @@ -476,15 +476,17 @@ static void list_all_cmds_help_aliases(int longest)\n>  \tstring_list_clear(&alias_list, 1);\n>  }\n>  \n> -void list_all_cmds_help(void)\n> +void list_all_cmds_help(int show_external_commands, int show_aliases)\n>  {\n>  \tint longest;\n>  \n>  \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n>  \tprint_cmd_by_category(main_categories, &longest);\n>  \n> -\tlist_all_cmds_help_external_commands();\n> -\tlist_all_cmds_help_aliases(longest);\n> +\tif (show_external_commands)\n> +\t\tlist_all_cmds_help_external_commands();\n> +\tif (show_aliases)\n> +\t\tlist_all_cmds_help_aliases(longest);\n>  }\n\nOK.  Quite straight-forward after the earlier split.\n\n"},{"id":"449360","messageId":"xmqqh78pqkph.fsf@gitster.g","threadId":"57159","inReplyTo":"patch-v2-9.9-08dc693dc3e-20220221T193708Z-avarab@gmail.com","subject":"Re: [PATCH v2 9/9] help: don't print \"\\n\" before single-section output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-23T22:31:06Z","receivedAt":"2022-02-23T22:31:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> @@ -124,7 +124,8 @@ static void print_cmd_by_category(const struct category_description *catdesc,\n>  \t\tuint32_t mask = catdesc[i].category;\n>  \t\tconst char *desc = catdesc[i].desc;\n>  \n> -\t\tputchar('\\n');\n> +\t\tif (i)\n> +\t\t\tputchar('\\n');\n>  \t\tputs(_(desc));\n>  \t\tprint_command_list(cmds, mask, longest);\n>  \t}\n> @@ -328,6 +329,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n>  void list_common_cmds_help(void)\n>  {\n>  \tputs(_(\"These are common Git commands used in various situations:\"));\n> +\tputchar('\\n');\n>  \tprint_cmd_by_category(common_categories, NULL);\n>  }\n>  \n> @@ -481,6 +483,7 @@ void list_all_cmds_help(int show_external_commands, int show_aliases)\n>  \tint longest;\n>  \n>  \tputs(_(\"See 'git help <command>' to read about a specific subcommand\"));\n> +\tputchar('\\n');\n>  \tprint_cmd_by_category(main_categories, &longest);\n>  \n>  \tif (show_external_commands)\n\n\nThis patch is a good example to demonstrate that some changes cannot\nbe reviewed without showing in the whole file what didn't get\nchanged.  Among three callers of print_cmd_by_category(), two of\nthem we see here are *not* the first to speak, and do add a blank\nline before the call.  The other caller that does not appear in the\npatch is what is being fixed, list_guides_help(), which has nobody\nto speak before it.\n\nThe correct pattern we want to follow in these messages is that\nbefore you say something, you add a blank line if somebody else has\nspoken before you.  It might make sense to tell these print_cmd_by*\nhelpers if they are the first to speak by passing the pointer to a\n\"state\" variable to indicate what has been emitted so far, instead\nof making the callers responsible to physically add blank lines, as\nthe callers would stop knowing if nobody else has spoken before them\nif we further refactor them and introduce new direct callers.\n\nIn any case, the posted patch itself looks OK.  After following\nthese 9 steps, I still do not see enough justification for the\nearlier \"use puts()\" step, except for correcting the misused\nprintf_ln().\n\nThanks, will queue the whole thing.\n\n\n> diff --git a/t/t0012-help.sh b/t/t0012-help.sh\n> index 64321480c68..6c3e1f7159d 100755\n> --- a/t/t0012-help.sh\n> +++ b/t/t0012-help.sh\n> @@ -226,7 +226,6 @@ test_expect_success \"'git help -a' section spacing\" '\n>  \n>  test_expect_success \"'git help -g' section spacing\" '\n>  \ttest_section_spacing_trailer git help -g <<-\\EOF &&\n> -\n>  \tThe Git concept guides are:\n>  \n>  \tEOF\n"}]}