Merge branch 'ab/help-fixes'
Updates to how command line options to "git help" are handled.
* ab/help-fixes:
  help: don't print "\n" before single-section output
  help: add --no-[external-commands|aliases] for use with --all
  help: error if [-a|-g|-c] and [-i|-m|-w] are combined
  help: correct usage & behavior of "git help --all"
  help: note the option name on option incompatibility
  help.c: split up list_all_cmds_help() function
  help tests: test "git" and "git help [-a|-g] spacing
  help.c: use puts() instead of printf{,_ln}() for consistency
  help doc: add missing "]" to "[-a|--all]"
			
			
This commit is contained in:
		| @ -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 | ||||
|  | ||||
| @ -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")); | ||||
|  | ||||
							
								
								
									
										37
									
								
								help.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								help.c
									
									
									
									
									
								
							| @ -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; | ||||
|  | ||||
							
								
								
									
										2
									
								
								help.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								help.h
									
									
									
									
									
								
							| @ -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); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Junio C Hamano
					Junio C Hamano