diff --git a/Makefile b/Makefile index cc635296a3..8d9f11e75e 100644 --- a/Makefile +++ b/Makefile @@ -327,7 +327,8 @@ LIB_OBJS = \ alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \ color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \ convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \ - transport.o bundle.o walker.o parse-options.o ws.o archive.o + transport.o bundle.o walker.o parse-options.o ws.o archive.o \ + alias.o BUILTIN_OBJS = \ builtin-add.o \ diff --git a/alias.c b/alias.c new file mode 100644 index 0000000000..116cac87c3 --- /dev/null +++ b/alias.c @@ -0,0 +1,22 @@ +#include "cache.h" + +static const char *alias_key; +static char *alias_val; +static int alias_lookup_cb(const char *k, const char *v) +{ + if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) { + if (!v) + return config_error_nonbool(k); + alias_val = xstrdup(v); + return 0; + } + return 0; +} + +char *alias_lookup(const char *alias) +{ + alias_key = alias; + alias_val = NULL; + git_config(alias_lookup_cb); + return alias_val; +} diff --git a/cache.h b/cache.h index 922bed9212..7769f055e9 100644 --- a/cache.h +++ b/cache.h @@ -768,4 +768,6 @@ int pathspec_match(const char **spec, char *matched, const char *filename, int s int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset); void overlay_tree_on_cache(const char *tree_name, const char *prefix); +char *alias_lookup(const char *alias); + #endif /* CACHE_H */ diff --git a/git.c b/git.c index 0cb86884d7..8f08b12295 100644 --- a/git.c +++ b/git.c @@ -87,19 +87,6 @@ static int handle_options(const char*** argv, int* argc, int* envchanged) return handled; } -static const char *alias_command; -static char *alias_string; - -static int git_alias_config(const char *var, const char *value) -{ - if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) { - if (!value) - return config_error_nonbool(var); - alias_string = xstrdup(value); - } - return 0; -} - static int split_cmdline(char *cmdline, const char ***argv) { int src, dst, count = 0, size = 16; @@ -159,11 +146,13 @@ static int handle_alias(int *argcp, const char ***argv) const char *subdir; int count, option_count; const char** new_argv; + const char *alias_command; + char *alias_string; subdir = setup_git_directory_gently(&nongit); alias_command = (*argv)[0]; - git_config(git_alias_config); + alias_string = alias_lookup(alias_command); if (alias_string) { if (alias_string[0] == '!') { if (*argcp > 1) { diff --git a/help.c b/help.c index 8143dcdd38..e57a50ed59 100644 --- a/help.c +++ b/help.c @@ -7,40 +7,49 @@ #include "builtin.h" #include "exec_cmd.h" #include "common-cmds.h" - -static const char *help_default_format; - -static enum help_format { - man_format, - info_format, - web_format, -} help_format = man_format; - -static void parse_help_format(const char *format) +#include "parse-options.h" + +enum help_format { + HELP_FORMAT_MAN, + HELP_FORMAT_INFO, + HELP_FORMAT_WEB, +}; + +static int show_all = 0; +static enum help_format help_format = HELP_FORMAT_MAN; +static struct option builtin_help_options[] = { + OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), + OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), + OPT_SET_INT('w', "web", &help_format, "show manual in web browser", + HELP_FORMAT_WEB), + OPT_SET_INT('i', "info", &help_format, "show info page", + HELP_FORMAT_INFO), +}; + +static const char * const builtin_help_usage[] = { + "git-help [--all] [--man|--web|--info] [command]", + NULL +}; + +static enum help_format parse_help_format(const char *format) { - if (!format) { - help_format = man_format; - return; - } - if (!strcmp(format, "man")) { - help_format = man_format; - return; - } - if (!strcmp(format, "info")) { - help_format = info_format; - return; - } - if (!strcmp(format, "web") || !strcmp(format, "html")) { - help_format = web_format; - return; - } + if (!strcmp(format, "man")) + return HELP_FORMAT_MAN; + if (!strcmp(format, "info")) + return HELP_FORMAT_INFO; + if (!strcmp(format, "web") || !strcmp(format, "html")) + return HELP_FORMAT_WEB; die("unrecognized help format '%s'", format); } static int git_help_config(const char *var, const char *value) { - if (!strcmp(var, "help.format")) - return git_config_string(&help_default_format, var, value); + if (!strcmp(var, "help.format")) { + if (!value) + return config_error_nonbool(var); + help_format = parse_help_format(value); + return 0; + } return git_default_config(var, value); } @@ -201,7 +210,7 @@ static unsigned int list_commands_in_dir(struct cmdnames *cmds, return longest; } -static void list_commands(void) +static unsigned int load_command_list(void) { unsigned int longest = 0; unsigned int len; @@ -241,6 +250,14 @@ static void list_commands(void) uniq(&other_cmds); exclude_cmds(&other_cmds, &main_cmds); + return longest; +} + +static void list_commands(void) +{ + unsigned int longest = load_command_list(); + const char *exec_path = git_exec_path(); + if (main_cmds.cnt) { printf("available git commands in '%s'\n", exec_path); printf("----------------------------"); @@ -275,6 +292,22 @@ void list_common_cmds_help(void) } } +static int is_in_cmdlist(struct cmdnames *c, const char *s) +{ + int i; + for (i = 0; i < c->cnt; i++) + if (!strcmp(s, c->names[i]->name)) + return 1; + return 0; +} + +static int is_git_command(const char *s) +{ + load_command_list(); + return is_in_cmdlist(&main_cmds, s) || + is_in_cmdlist(&other_cmds, s); +} + static const char *cmd_to_page(const char *git_cmd) { if (!git_cmd) @@ -362,50 +395,43 @@ int cmd_version(int argc, const char **argv, const char *prefix) int cmd_help(int argc, const char **argv, const char *prefix) { - const char *help_cmd = argv[1]; + int nongit; + const char *alias; - if (argc < 2) { - printf("usage: %s\n\n", git_usage_string); - list_common_cmds_help(); - exit(0); - } + setup_git_directory_gently(&nongit); + git_config(git_help_config); + + argc = parse_options(argc, argv, builtin_help_options, + builtin_help_usage, 0); - if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) { + if (show_all) { printf("usage: %s\n\n", git_usage_string); list_commands(); + return 0; } - else if (!strcmp(help_cmd, "--web") || !strcmp(help_cmd, "-w")) { - show_html_page(argc > 2 ? argv[2] : NULL); - } - - else if (!strcmp(help_cmd, "--info") || !strcmp(help_cmd, "-i")) { - show_info_page(argc > 2 ? argv[2] : NULL); + if (!argv[0]) { + printf("usage: %s\n\n", git_usage_string); + list_common_cmds_help(); + return 0; } - else if (!strcmp(help_cmd, "--man") || !strcmp(help_cmd, "-m")) { - show_man_page(argc > 2 ? argv[2] : NULL); + alias = alias_lookup(argv[0]); + if (alias && !is_git_command(argv[0])) { + printf("`git %s' is aliased to `%s'\n", argv[0], alias); + return 0; } - else { - int nongit; - - setup_git_directory_gently(&nongit); - git_config(git_help_config); - if (help_default_format) - parse_help_format(help_default_format); - - switch (help_format) { - case man_format: - show_man_page(help_cmd); - break; - case info_format: - show_info_page(help_cmd); - break; - case web_format: - show_html_page(help_cmd); - break; - } + switch (help_format) { + case HELP_FORMAT_MAN: + show_man_page(argv[0]); + break; + case HELP_FORMAT_INFO: + show_info_page(argv[0]); + break; + case HELP_FORMAT_WEB: + show_html_page(argv[0]); + break; } return 0;