diff options
-rw-r--r-- | Documentation/git-help.txt | 15 | ||||
-rw-r--r-- | builtin/help.c | 63 | ||||
-rw-r--r-- | help.c | 37 | ||||
-rw-r--r-- | help.h | 2 | ||||
-rwxr-xr-x | t/t0012-help.sh | 94 |
5 files changed, 187 insertions, 24 deletions
diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index 44ea63cc6d..239c68db45 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -8,8 +8,8 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all [--[no-]verbose]] - [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>] +'git help' [-a|--all] [--[no-]verbose] [--[no-]external-commands] [--[no-]aliases] +'git help' [[-i|--info] [-m|--man] [-w|--web]] [<command>|<guide>] 'git help' [-g|--guides] 'git help' [-c|--config] @@ -46,8 +46,15 @@ OPTIONS ------- -a:: --all:: - Prints all the available commands on the standard output. This - option overrides any given command or guide name. + Prints all the available commands on the standard output. + +--no-external-commands:: + When used with `--all`, exclude the listing of external "git-*" + commands found in the `$PATH`. + +--no-aliases:: + When used with `--all`, exclude the listing of configured + aliases. --verbose:: When used with `--all` print description for all recognized diff --git a/builtin/help.c b/builtin/help.c index b4f2ad3f94..222f994f86 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -51,9 +51,14 @@ static const char *html_path; static int verbose = 1; static enum help_format help_format = HELP_FORMAT_NONE; static int exclude_guides; +static int show_external_commands = -1; +static int show_aliases = -1; static struct option builtin_help_options[] = { OPT_CMDMODE('a', "all", &cmd_mode, N_("print all available commands"), HELP_ACTION_ALL), + OPT_BOOL(0, "external-commands", &show_external_commands, + N_("show external commands in --all")), + OPT_BOOL(0, "aliases", &show_aliases, N_("show aliases in --all")), OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")), OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN), OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"), @@ -75,8 +80,8 @@ static struct option builtin_help_options[] = { }; static const char * const builtin_help_usage[] = { - N_("git help [-a|--all] [--[no-]verbose]]\n" - " [[-i|--info] [-m|--man] [-w|--web]] [<command>]"), + "git help [-a|--all] [--[no-]verbose]] [--[no-]external-commands] [--[no-]aliases]", + N_("git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"), "git help [-g|--guides]", "git help [-c|--config]", NULL @@ -574,11 +579,40 @@ static const char *check_git_cmd(const char* cmd) return cmd; } -static void no_extra_argc(int argc) +static void no_help_format(const char *opt_mode, enum help_format fmt) +{ + const char *opt_fmt; + + switch (fmt) { + case HELP_FORMAT_NONE: + return; + case HELP_FORMAT_MAN: + opt_fmt = "--man"; + break; + case HELP_FORMAT_INFO: + opt_fmt = "--info"; + break; + case HELP_FORMAT_WEB: + opt_fmt = "--web"; + break; + default: + BUG("unreachable"); + } + + usage_msg_optf(_("options '%s' and '%s' cannot be used together"), + builtin_help_usage, builtin_help_options, opt_mode, + opt_fmt); +} + +static void opt_mode_usage(int argc, const char *opt_mode, + enum help_format fmt) { if (argc) - usage_msg_opt(_("this option doesn't take any other arguments"), - builtin_help_usage, builtin_help_options); + usage_msg_optf(_("the '%s' option doesn't take any non-option arguments"), + builtin_help_usage, builtin_help_options, + opt_mode); + + no_help_format(opt_mode, fmt); } int cmd_help(int argc, const char **argv, const char *prefix) @@ -591,11 +625,19 @@ int cmd_help(int argc, const char **argv, const char *prefix) builtin_help_usage, 0); parsed_help_format = help_format; + if (cmd_mode != HELP_ACTION_ALL && + (show_external_commands >= 0 || + show_aliases >= 0)) + usage_msg_opt(_("the '--no-[external-commands|aliases]' options can only be used with '--all'"), + builtin_help_usage, builtin_help_options); + switch (cmd_mode) { case HELP_ACTION_ALL: + opt_mode_usage(argc, "--all", help_format); if (verbose) { setup_pager(); - list_all_cmds_help(); + list_all_cmds_help(show_external_commands, + show_aliases); return 0; } printf(_("usage: %s%s"), _(git_usage_string), "\n\n"); @@ -604,20 +646,21 @@ int cmd_help(int argc, const char **argv, const char *prefix) printf("%s\n", _(git_more_info_string)); break; case HELP_ACTION_GUIDES: - no_extra_argc(argc); + opt_mode_usage(argc, "--guides", help_format); list_guides_help(); printf("%s\n", _(git_more_info_string)); return 0; case HELP_ACTION_CONFIG_FOR_COMPLETION: - no_extra_argc(argc); + opt_mode_usage(argc, "--config-for-completion", help_format); list_config_help(SHOW_CONFIG_VARS); return 0; case HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION: - no_extra_argc(argc); + opt_mode_usage(argc, "--config-sections-for-completion", + help_format); list_config_help(SHOW_CONFIG_SECTIONS); return 0; case HELP_ACTION_CONFIG: - no_extra_argc(argc); + opt_mode_usage(argc, "--config", help_format); setup_pager(); list_config_help(SHOW_CONFIG_HUMAN); printf("\n%s\n", _("'git help config' for more information")); @@ -124,7 +124,9 @@ static void print_cmd_by_category(const struct category_description *catdesc, uint32_t mask = catdesc[i].category; const char *desc = catdesc[i].desc; - printf("\n%s\n", _(desc)); + if (i) + putchar('\n'); + puts(_(desc)); print_command_list(cmds, mask, longest); } free(cmds); @@ -317,7 +319,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds) } if (other_cmds->cnt) { - printf_ln(_("git commands available from elsewhere on your $PATH")); + puts(_("git commands available from elsewhere on your $PATH")); putchar('\n'); pretty_print_cmdnames(other_cmds, colopts); putchar('\n'); @@ -327,6 +329,7 @@ void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds) void list_common_cmds_help(void) { puts(_("These are common Git commands used in various situations:")); + putchar('\n'); print_cmd_by_category(common_categories, NULL); } @@ -432,15 +435,10 @@ static int get_alias(const char *var, const char *value, void *data) return 0; } -void list_all_cmds_help(void) +static void list_all_cmds_help_external_commands(void) { struct string_list others = STRING_LIST_INIT_DUP; - struct string_list alias_list = STRING_LIST_INIT_DUP; - struct cmdname_help *aliases; - int i, longest; - - printf_ln(_("See 'git help <command>' to read about a specific subcommand")); - print_cmd_by_category(main_categories, &longest); + int i; list_all_other_cmds(&others); if (others.nr) @@ -448,6 +446,13 @@ void list_all_cmds_help(void) for (i = 0; i < others.nr; i++) printf(" %s\n", others.items[i].string); string_list_clear(&others, 0); +} + +static void list_all_cmds_help_aliases(int longest) +{ + struct string_list alias_list = STRING_LIST_INIT_DUP; + struct cmdname_help *aliases; + int i; git_config(get_alias, &alias_list); string_list_sort(&alias_list); @@ -473,6 +478,20 @@ void list_all_cmds_help(void) string_list_clear(&alias_list, 1); } +void list_all_cmds_help(int show_external_commands, int show_aliases) +{ + int longest; + + puts(_("See 'git help <command>' to read about a specific subcommand")); + putchar('\n'); + print_cmd_by_category(main_categories, &longest); + + if (show_external_commands) + list_all_cmds_help_external_commands(); + if (show_aliases) + list_all_cmds_help_aliases(longest); +} + int is_in_cmdlist(struct cmdnames *c, const char *s) { int i; @@ -20,7 +20,7 @@ static inline void mput_char(char c, unsigned int num) } void list_common_cmds_help(void); -void list_all_cmds_help(void); +void list_all_cmds_help(int show_external_commands, int show_aliases); void list_guides_help(void); void list_all_main_cmds(struct string_list *list); diff --git a/t/t0012-help.sh b/t/t0012-help.sh index cbd725ccac..6c3e1f7159 100755 --- a/t/t0012-help.sh +++ b/t/t0012-help.sh @@ -35,6 +35,9 @@ test_expect_success 'basic help commands' ' ' test_expect_success 'invalid usage' ' + test_expect_code 129 git help -a add && + test_expect_code 129 git help --all add && + test_expect_code 129 git help -g add && test_expect_code 129 git help -a -c && @@ -46,6 +49,29 @@ test_expect_success 'invalid usage' ' test_expect_code 129 git help --config-sections-for-completion add ' +for opt in '-a' '-g' '-c' '--config-for-completion' '--config-sections-for-completion' +do + test_expect_success "invalid usage of '$opt' with [-i|-m|-w]" ' + git help $opt && + test_expect_code 129 git help $opt -i && + test_expect_code 129 git help $opt -m && + test_expect_code 129 git help $opt -w + ' + + if test "$opt" = "-a" + then + continue + fi + + test_expect_success "invalid usage of '$opt' with --no-external-commands" ' + test_expect_code 129 git help $opt --no-external-commands + ' + + test_expect_success "invalid usage of '$opt' with --no-aliases" ' + test_expect_code 129 git help $opt --no-external-commands + ' +done + test_expect_success "works for commands and guides by default" ' configure_help && git help status && @@ -138,6 +164,74 @@ test_expect_success 'git help --config-sections-for-completion' ' test_cmp human.munged sections ' +test_section_spacing () { + cat >expect && + "$@" >out && + grep -E "(^[^ ]|^$)" out >actual +} + +test_section_spacing_trailer () { + test_section_spacing "$@" && + test_expect_code 1 git >out && + sed -n '/list available subcommands/,$p' <out >>expect +} + + +for cmd in git "git help" +do + test_expect_success "'$cmd' section spacing" ' + test_section_spacing_trailer git help <<-\EOF && + usage: git [--version] [--help] [-C <path>] [-c <name>=<value>] + + These are common Git commands used in various situations: + + start a working area (see also: git help tutorial) + + work on the current change (see also: git help everyday) + + examine the history and state (see also: git help revisions) + + grow, mark and tweak your common history + + collaborate (see also: git help workflows) + + EOF + test_cmp expect actual + ' +done + +test_expect_success "'git help -a' section spacing" ' + test_section_spacing \ + git help -a --no-external-commands --no-aliases <<-\EOF && + See '\''git help <command>'\'' to read about a specific subcommand + + Main Porcelain Commands + + Ancillary Commands / Manipulators + + Ancillary Commands / Interrogators + + Interacting with Others + + Low-level Commands / Manipulators + + Low-level Commands / Interrogators + + Low-level Commands / Syncing Repositories + + Low-level Commands / Internal Helpers + EOF + test_cmp expect actual +' + +test_expect_success "'git help -g' section spacing" ' + test_section_spacing_trailer git help -g <<-\EOF && + The Git concept guides are: + + EOF + test_cmp expect actual +' + test_expect_success 'generate builtin list' ' mkdir -p sub && git --list-cmds=builtins >builtins |