{"thread":{"id":"35950","subject":"[PATCH] help: include list of aliases in git-help --all","startedAt":"2014-02-25T00:48:34Z","lastAt":"2014-02-25T23:22:24Z","messageCount":7,"participants":["Joel Nothman","Junio C Hamano","Philip Oakley"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"235311","messageId":"1393289315-28982-1-git-send-email-joel.nothman@gmail.com","threadId":"35950","inReplyTo":null,"subject":"[PATCH] help: include list of aliases in git-help --all","fromName":"Joel Nothman","fromEmail":"joel.nothman@gmail.com","sentAt":"2014-02-25T00:48:34Z","receivedAt":"2014-02-25T00:48:34Z","isPatch":true,"sender":{"key":"joel.nothman@gmail.com","avatar":"https://gravatar.com/avatar/8da89a7c58a878272b07d3c16cf8c8cd08e3b1cf287e0b330aadca470cb07608?d=mp&s=160"},"body":"Git help --all had listed all git commands, but no configured aliases.\nThis includes aliases as a separate listing, after commands in the main\ngit directory and other $PATH directories.\n\nSigned-off-by: Joel Nothman <joel.nothman <at> gmail.com>\n---\n Documentation/git-help.txt |  4 +--\n builtin/help.c             |  7 ++---\n help.c                     | 64 +++++++++++++++++++++++++++++++++++-----------\n help.h                     |  7 ++++-\n 4 files changed, 61 insertions(+), 21 deletions(-)\n\ndiff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\nindex b21e9d7..c9fe791 100644\n--- a/Documentation/git-help.txt\n+++ b/Documentation/git-help.txt\n@@ -40,8 +40,8 @@ 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 and aliases on the standard output.\n+\tThis option overrides any given command or guide name.\n \n -g::\n --guides::\ndiff --git a/builtin/help.c b/builtin/help.c\nindex 1fdefeb..d1dfecd 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -38,7 +38,7 @@ static int show_guides = 0;\n static unsigned int colopts;\n static enum help_format help_format = HELP_FORMAT_NONE;\n static struct option builtin_help_options[] = {\n-\tOPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands\")),\n+\tOPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands and aliases\")),\n \tOPT_BOOL('g', \"guides\", &show_guides, N_(\"print list of useful 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@@ -453,6 +453,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \tint nongit;\n \tconst char *alias;\n \tenum help_format parsed_help_format;\n+\tstruct cmdnames alias_cmds;\n \n \targc = parse_options(argc, argv, prefix, builtin_help_options,\n \t\t\tbuiltin_help_usage, 0);\n@@ -461,8 +462,8 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n \tif (show_all) {\n \t\tgit_config(git_help_config, NULL);\n \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n-\t\tload_command_list(\"git-\", &main_cmds, &other_cmds);\n-\t\tlist_commands(colopts, &main_cmds, &other_cmds);\n+\t\tload_commands_and_aliases(\"git-\", &main_cmds, &other_cmds, &alias_cmds);\n+\t\tlist_commands(colopts, &main_cmds, &other_cmds, &alias_cmds);\n \t}\n \n \tif (show_guides)\ndiff --git a/help.c b/help.c\nindex df7d16d..3c14af4 100644\n--- a/help.c\n+++ b/help.c\n@@ -86,7 +86,7 @@ static void pretty_print_string_list(struct cmdnames *cmds,\n \tint i;\n \n \tfor (i = 0; i < cmds->cnt; i++)\n-\t\tstring_list_append(&list, cmds->names[i]->name);\n+\t    string_list_append(&list, cmds->names[i]->name);\n \t/*\n \t * always enable column display, we only consult column.*\n \t * about layout strategy and stuff\n@@ -202,8 +202,48 @@ void load_command_list(const char *prefix,\n \texclude_cmds(other_cmds, main_cmds);\n }\n \n+static struct cmdnames aliases;\n+\n+static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n+{\n+\tint i;\n+\tALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n+\n+\tfor (i = 0; i < old->cnt; i++)\n+\t\tcmds->names[cmds->cnt++] = old->names[i];\n+\tfree(old->names);\n+\told->cnt = 0;\n+\told->names = NULL;\n+}\n+\n+static int load_aliases_cb(const char *var, const char *value, void *cb)\n+{\n+\tif (starts_with(var, \"alias.\"))\n+\t\tadd_cmdname(&aliases, var + 6, strlen(var + 6));\n+\treturn 0;\n+}\n+\n+void load_commands_and_aliases(const char *prefix,\n+\t\tstruct cmdnames *main_cmds,\n+\t\tstruct cmdnames *other_cmds,\n+\t\tstruct cmdnames *alias_cmds)\n+{\n+\tload_command_list(prefix, main_cmds, other_cmds);\n+\n+\t/* reuses global aliases from unknown command functionality */\n+\tgit_config(load_aliases_cb, NULL);\n+\n+\tadd_cmd_list(alias_cmds, &aliases);\n+\tqsort(alias_cmds->names, alias_cmds->cnt,\n+\t\t  sizeof(*alias_cmds->names), cmdname_compare);\n+\tuniq(alias_cmds);\n+\texclude_cmds(alias_cmds, main_cmds);\n+\texclude_cmds(alias_cmds, other_cmds);\n+}\n+\n void list_commands(unsigned int colopts,\n-\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n+\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds,\n+\t\t   struct cmdnames *alias_cmds)\n {\n \tif (main_cmds->cnt) {\n \t\tconst char *exec_path = git_exec_path();\n@@ -219,6 +259,13 @@ void list_commands(unsigned int colopts,\n \t\tpretty_print_string_list(other_cmds, colopts);\n \t\tputchar('\\n');\n \t}\n+\n+\tif (alias_cmds->cnt) {\n+\t\tprintf_ln(_(\"aliases defined in git configuration\"));\n+\t\tputchar('\\n');\n+\t\tpretty_print_string_list(alias_cmds, colopts);\n+\t\tputchar('\\n');\n+\t}\n }\n \n void list_common_cmds_help(void)\n@@ -248,7 +295,6 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)\n }\n \n static int autocorrect;\n-static struct cmdnames aliases;\n \n static int git_unknown_cmd_config(const char *var, const char *value, void *cb)\n {\n@@ -270,18 +316,6 @@ static int levenshtein_compare(const void *p1, const void *p2)\n \treturn l1 != l2 ? l1 - l2 : strcmp(s1, s2);\n }\n \n-static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n-{\n-\tint i;\n-\tALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n-\n-\tfor (i = 0; i < old->cnt; i++)\n-\t\tcmds->names[cmds->cnt++] = old->names[i];\n-\tfree(old->names);\n-\told->cnt = 0;\n-\told->names = NULL;\n-}\n-\n /* An empirically derived magic number */\n #define SIMILARITY_FLOOR 7\n #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)\ndiff --git a/help.h b/help.h\nindex b21d7c9..3939bc6 100644\n--- a/help.h\n+++ b/help.h\n@@ -21,11 +21,16 @@ extern const char *help_unknown_cmd(const char *cmd);\n extern void load_command_list(const char *prefix,\n \t\t\t      struct cmdnames *main_cmds,\n \t\t\t      struct cmdnames *other_cmds);\n+extern void load_commands_and_aliases(const char *prefix,\n+\t\t\t      struct cmdnames *main_cmds,\n+\t\t\t      struct cmdnames *other_cmds,\n+\t\t\t      struct cmdnames *alias_cmds);\n extern void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n /* Here we require that excludes is a sorted list. */\n extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n-extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);\n+extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds,\n+\t\t\t  struct cmdnames *other_cmds, struct cmdnames *alias_cmds);\n \n /*\n  * call this to die(), when it is suspected that the user mistyped a\n-- \n1.8.3.4 (Apple Git-47)\n"},{"id":"235332","messageId":"xmqqsir757hy.fsf@gitster.dls.corp.google.com","threadId":"35950","inReplyTo":"1393289315-28982-1-git-send-email-joel.nothman@gmail.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-02-25T19:15:21Z","receivedAt":"2014-02-25T19:15:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Joel Nothman <joel.nothman@gmail.com> writes:\n\n> Git help --all had listed all git commands, but no configured aliases.\n> This includes aliases as a separate listing, after commands in the main\n> git directory and other $PATH directories.\n\n... and why is this a good thing?\n\n>\n> Signed-off-by: Joel Nothman <joel.nothman <at> gmail.com>\n> ---\n>  Documentation/git-help.txt |  4 +--\n>  builtin/help.c             |  7 ++---\n>  help.c                     | 64 +++++++++++++++++++++++++++++++++++-----------\n>  help.h                     |  7 ++++-\n>  4 files changed, 61 insertions(+), 21 deletions(-)\n>\n> diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\n> index b21e9d7..c9fe791 100644\n> --- a/Documentation/git-help.txt\n> +++ b/Documentation/git-help.txt\n> @@ -40,8 +40,8 @@ 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 and aliases on the standard output.\n> +\tThis option overrides any given command or guide name.\n>  \n>  -g::\n>  --guides::\n> diff --git a/builtin/help.c b/builtin/help.c\n> index 1fdefeb..d1dfecd 100644\n> --- a/builtin/help.c\n> +++ b/builtin/help.c\n> @@ -38,7 +38,7 @@ static int show_guides = 0;\n>  static unsigned int colopts;\n>  static enum help_format help_format = HELP_FORMAT_NONE;\n>  static struct option builtin_help_options[] = {\n> -\tOPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands\")),\n> +\tOPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands and aliases\")),\n>  \tOPT_BOOL('g', \"guides\", &show_guides, N_(\"print list of useful 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> @@ -453,6 +453,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>  \tint nongit;\n>  \tconst char *alias;\n>  \tenum help_format parsed_help_format;\n> +\tstruct cmdnames alias_cmds;\n>  \n>  \targc = parse_options(argc, argv, prefix, builtin_help_options,\n>  \t\t\tbuiltin_help_usage, 0);\n> @@ -461,8 +462,8 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>  \tif (show_all) {\n>  \t\tgit_config(git_help_config, NULL);\n>  \t\tprintf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n> -\t\tload_command_list(\"git-\", &main_cmds, &other_cmds);\n> -\t\tlist_commands(colopts, &main_cmds, &other_cmds);\n> +\t\tload_commands_and_aliases(\"git-\", &main_cmds, &other_cmds, &alias_cmds);\n> +\t\tlist_commands(colopts, &main_cmds, &other_cmds, &alias_cmds);\n>  \t}\n>  \n>  \tif (show_guides)\n> diff --git a/help.c b/help.c\n> index df7d16d..3c14af4 100644\n> --- a/help.c\n> +++ b/help.c\n> @@ -86,7 +86,7 @@ static void pretty_print_string_list(struct cmdnames *cmds,\n>  \tint i;\n>  \n>  \tfor (i = 0; i < cmds->cnt; i++)\n> -\t\tstring_list_append(&list, cmds->names[i]->name);\n> +\t    string_list_append(&list, cmds->names[i]->name);\n>  \t/*\n>  \t * always enable column display, we only consult column.*\n>  \t * about layout strategy and stuff\n> @@ -202,8 +202,48 @@ void load_command_list(const char *prefix,\n>  \texclude_cmds(other_cmds, main_cmds);\n>  }\n>  \n> +static struct cmdnames aliases;\n> +\n> +static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n> +{\n> +\tint i;\n> +\tALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n> +\n> +\tfor (i = 0; i < old->cnt; i++)\n> +\t\tcmds->names[cmds->cnt++] = old->names[i];\n> +\tfree(old->names);\n> +\told->cnt = 0;\n> +\told->names = NULL;\n> +}\n> +\n> +static int load_aliases_cb(const char *var, const char *value, void *cb)\n> +{\n> +\tif (starts_with(var, \"alias.\"))\n> +\t\tadd_cmdname(&aliases, var + 6, strlen(var + 6));\n> +\treturn 0;\n> +}\n> +\n> +void load_commands_and_aliases(const char *prefix,\n> +\t\tstruct cmdnames *main_cmds,\n> +\t\tstruct cmdnames *other_cmds,\n> +\t\tstruct cmdnames *alias_cmds)\n> +{\n> +\tload_command_list(prefix, main_cmds, other_cmds);\n> +\n> +\t/* reuses global aliases from unknown command functionality */\n> +\tgit_config(load_aliases_cb, NULL);\n> +\n> +\tadd_cmd_list(alias_cmds, &aliases);\n> +\tqsort(alias_cmds->names, alias_cmds->cnt,\n> +\t\t  sizeof(*alias_cmds->names), cmdname_compare);\n> +\tuniq(alias_cmds);\n> +\texclude_cmds(alias_cmds, main_cmds);\n> +\texclude_cmds(alias_cmds, other_cmds);\n> +}\n> +\n>  void list_commands(unsigned int colopts,\n> -\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n> +\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds,\n> +\t\t   struct cmdnames *alias_cmds)\n>  {\n>  \tif (main_cmds->cnt) {\n>  \t\tconst char *exec_path = git_exec_path();\n> @@ -219,6 +259,13 @@ void list_commands(unsigned int colopts,\n>  \t\tpretty_print_string_list(other_cmds, colopts);\n>  \t\tputchar('\\n');\n>  \t}\n> +\n> +\tif (alias_cmds->cnt) {\n> +\t\tprintf_ln(_(\"aliases defined in git configuration\"));\n> +\t\tputchar('\\n');\n> +\t\tpretty_print_string_list(alias_cmds, colopts);\n> +\t\tputchar('\\n');\n> +\t}\n>  }\n>  \n>  void list_common_cmds_help(void)\n> @@ -248,7 +295,6 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)\n>  }\n>  \n>  static int autocorrect;\n> -static struct cmdnames aliases;\n>  \n>  static int git_unknown_cmd_config(const char *var, const char *value, void *cb)\n>  {\n> @@ -270,18 +316,6 @@ static int levenshtein_compare(const void *p1, const void *p2)\n>  \treturn l1 != l2 ? l1 - l2 : strcmp(s1, s2);\n>  }\n>  \n> -static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n> -{\n> -\tint i;\n> -\tALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n> -\n> -\tfor (i = 0; i < old->cnt; i++)\n> -\t\tcmds->names[cmds->cnt++] = old->names[i];\n> -\tfree(old->names);\n> -\told->cnt = 0;\n> -\told->names = NULL;\n> -}\n> -\n>  /* An empirically derived magic number */\n>  #define SIMILARITY_FLOOR 7\n>  #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)\n> diff --git a/help.h b/help.h\n> index b21d7c9..3939bc6 100644\n> --- a/help.h\n> +++ b/help.h\n> @@ -21,11 +21,16 @@ extern const char *help_unknown_cmd(const char *cmd);\n>  extern void load_command_list(const char *prefix,\n>  \t\t\t      struct cmdnames *main_cmds,\n>  \t\t\t      struct cmdnames *other_cmds);\n> +extern void load_commands_and_aliases(const char *prefix,\n> +\t\t\t      struct cmdnames *main_cmds,\n> +\t\t\t      struct cmdnames *other_cmds,\n> +\t\t\t      struct cmdnames *alias_cmds);\n>  extern void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n>  /* Here we require that excludes is a sorted list. */\n>  extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n>  extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n> -extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);\n> +extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds,\n> +\t\t\t  struct cmdnames *other_cmds, struct cmdnames *alias_cmds);\n>  \n>  /*\n>   * call this to die(), when it is suspected that the user mistyped a\n"},{"id":"235336","messageId":"CAAkaFLVRP3WF=2hyBo9uxutJ8iLPyBVkiBs=29xN13762r32Bg@mail.gmail.com","threadId":"35950","inReplyTo":"xmqqsir757hy.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Joel Nothman","fromEmail":"joel.nothman@gmail.com","sentAt":"2014-02-25T21:20:18Z","receivedAt":"2014-02-25T21:20:18Z","isPatch":true,"sender":{"key":"joel.nothman@gmail.com","avatar":"https://gravatar.com/avatar/8da89a7c58a878272b07d3c16cf8c8cd08e3b1cf287e0b330aadca470cb07608?d=mp&s=160"},"body":"On 26 February 2014 06:15, Junio C Hamano <gitster@pobox.com> wrote:\n> Joel Nothman <joel.nothman@gmail.com> writes:\n>\n>> Git help --all had listed all git commands, but no configured aliases.\n>> This includes aliases as a separate listing, after commands in the main\n>> git directory and other $PATH directories.\n>\n> ... and why is this a good thing?\n\nA fair question: I had considered it a conspicuous absence from the\nlist of commands in git help. After all, aliases are treated like\ncommands for a few purposes: they are executed as commands, they are\nlisted as possible command spelling corrections, and they are valid\narguments to git help. They are also like commands in that it is\npossible to forget their name, or whether they are defined on a\nparticular workstation, and to hence want a listing. A user may also\nnot recall whether they had implemented a particular shortcut as an\nalias or as a script (one may initially implement a script, and\nrealise an alias is sufficient; one may at first implement an alias\nand realise it is insufficient, and that a script is needed).\n\nIn short, for many of the purposes in which one would seek git help\n-a, there is no reason to *exclude* aliases from a list of commands\nexecuted likewise.\n\n>>\n>> Signed-off-by: Joel Nothman <joel.nothman <at> gmail.com>\n>> ---\n>>  Documentation/git-help.txt |  4 +--\n>>  builtin/help.c             |  7 ++---\n>>  help.c                     | 64 +++++++++++++++++++++++++++++++++++-----------\n>>  help.h                     |  7 ++++-\n>>  4 files changed, 61 insertions(+), 21 deletions(-)\n>>\n>> diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\n>> index b21e9d7..c9fe791 100644\n>> --- a/Documentation/git-help.txt\n>> +++ b/Documentation/git-help.txt\n>> @@ -40,8 +40,8 @@ OPTIONS\n>>  -------\n>>  -a::\n>>  --all::\n>> -     Prints all the available commands on the standard output. This\n>> -     option overrides any given command or guide name.\n>> +     Prints all the available commands and aliases on the standard output.\n>> +     This option overrides any given command or guide name.\n>>\n>>  -g::\n>>  --guides::\n>> diff --git a/builtin/help.c b/builtin/help.c\n>> index 1fdefeb..d1dfecd 100644\n>> --- a/builtin/help.c\n>> +++ b/builtin/help.c\n>> @@ -38,7 +38,7 @@ static int show_guides = 0;\n>>  static unsigned int colopts;\n>>  static enum help_format help_format = HELP_FORMAT_NONE;\n>>  static struct option builtin_help_options[] = {\n>> -     OPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands\")),\n>> +     OPT_BOOL('a', \"all\", &show_all, N_(\"print all available commands and aliases\")),\n>>       OPT_BOOL('g', \"guides\", &show_guides, N_(\"print list of useful guides\")),\n>>       OPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), HELP_FORMAT_MAN),\n>>       OPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web browser\"),\n>> @@ -453,6 +453,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>>       int nongit;\n>>       const char *alias;\n>>       enum help_format parsed_help_format;\n>> +     struct cmdnames alias_cmds;\n>>\n>>       argc = parse_options(argc, argv, prefix, builtin_help_options,\n>>                       builtin_help_usage, 0);\n>> @@ -461,8 +462,8 @@ int cmd_help(int argc, const char **argv, const char *prefix)\n>>       if (show_all) {\n>>               git_config(git_help_config, NULL);\n>>               printf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n>> -             load_command_list(\"git-\", &main_cmds, &other_cmds);\n>> -             list_commands(colopts, &main_cmds, &other_cmds);\n>> +             load_commands_and_aliases(\"git-\", &main_cmds, &other_cmds, &alias_cmds);\n>> +             list_commands(colopts, &main_cmds, &other_cmds, &alias_cmds);\n>>       }\n>>\n>>       if (show_guides)\n>> diff --git a/help.c b/help.c\n>> index df7d16d..3c14af4 100644\n>> --- a/help.c\n>> +++ b/help.c\n>> @@ -86,7 +86,7 @@ static void pretty_print_string_list(struct cmdnames *cmds,\n>>       int i;\n>>\n>>       for (i = 0; i < cmds->cnt; i++)\n>> -             string_list_append(&list, cmds->names[i]->name);\n>> +         string_list_append(&list, cmds->names[i]->name);\n>>       /*\n>>        * always enable column display, we only consult column.*\n>>        * about layout strategy and stuff\n>> @@ -202,8 +202,48 @@ void load_command_list(const char *prefix,\n>>       exclude_cmds(other_cmds, main_cmds);\n>>  }\n>>\n>> +static struct cmdnames aliases;\n>> +\n>> +static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n>> +{\n>> +     int i;\n>> +     ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n>> +\n>> +     for (i = 0; i < old->cnt; i++)\n>> +             cmds->names[cmds->cnt++] = old->names[i];\n>> +     free(old->names);\n>> +     old->cnt = 0;\n>> +     old->names = NULL;\n>> +}\n>> +\n>> +static int load_aliases_cb(const char *var, const char *value, void *cb)\n>> +{\n>> +     if (starts_with(var, \"alias.\"))\n>> +             add_cmdname(&aliases, var + 6, strlen(var + 6));\n>> +     return 0;\n>> +}\n>> +\n>> +void load_commands_and_aliases(const char *prefix,\n>> +             struct cmdnames *main_cmds,\n>> +             struct cmdnames *other_cmds,\n>> +             struct cmdnames *alias_cmds)\n>> +{\n>> +     load_command_list(prefix, main_cmds, other_cmds);\n>> +\n>> +     /* reuses global aliases from unknown command functionality */\n>> +     git_config(load_aliases_cb, NULL);\n>> +\n>> +     add_cmd_list(alias_cmds, &aliases);\n>> +     qsort(alias_cmds->names, alias_cmds->cnt,\n>> +               sizeof(*alias_cmds->names), cmdname_compare);\n>> +     uniq(alias_cmds);\n>> +     exclude_cmds(alias_cmds, main_cmds);\n>> +     exclude_cmds(alias_cmds, other_cmds);\n>> +}\n>> +\n>>  void list_commands(unsigned int colopts,\n>> -                struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n>> +                struct cmdnames *main_cmds, struct cmdnames *other_cmds,\n>> +                struct cmdnames *alias_cmds)\n>>  {\n>>       if (main_cmds->cnt) {\n>>               const char *exec_path = git_exec_path();\n>> @@ -219,6 +259,13 @@ void list_commands(unsigned int colopts,\n>>               pretty_print_string_list(other_cmds, colopts);\n>>               putchar('\\n');\n>>       }\n>> +\n>> +     if (alias_cmds->cnt) {\n>> +             printf_ln(_(\"aliases defined in git configuration\"));\n>> +             putchar('\\n');\n>> +             pretty_print_string_list(alias_cmds, colopts);\n>> +             putchar('\\n');\n>> +     }\n>>  }\n>>\n>>  void list_common_cmds_help(void)\n>> @@ -248,7 +295,6 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)\n>>  }\n>>\n>>  static int autocorrect;\n>> -static struct cmdnames aliases;\n>>\n>>  static int git_unknown_cmd_config(const char *var, const char *value, void *cb)\n>>  {\n>> @@ -270,18 +316,6 @@ static int levenshtein_compare(const void *p1, const void *p2)\n>>       return l1 != l2 ? l1 - l2 : strcmp(s1, s2);\n>>  }\n>>\n>> -static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)\n>> -{\n>> -     int i;\n>> -     ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n>> -\n>> -     for (i = 0; i < old->cnt; i++)\n>> -             cmds->names[cmds->cnt++] = old->names[i];\n>> -     free(old->names);\n>> -     old->cnt = 0;\n>> -     old->names = NULL;\n>> -}\n>> -\n>>  /* An empirically derived magic number */\n>>  #define SIMILARITY_FLOOR 7\n>>  #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)\n>> diff --git a/help.h b/help.h\n>> index b21d7c9..3939bc6 100644\n>> --- a/help.h\n>> +++ b/help.h\n>> @@ -21,11 +21,16 @@ extern const char *help_unknown_cmd(const char *cmd);\n>>  extern void load_command_list(const char *prefix,\n>>                             struct cmdnames *main_cmds,\n>>                             struct cmdnames *other_cmds);\n>> +extern void load_commands_and_aliases(const char *prefix,\n>> +                           struct cmdnames *main_cmds,\n>> +                           struct cmdnames *other_cmds,\n>> +                           struct cmdnames *alias_cmds);\n>>  extern void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n>>  /* Here we require that excludes is a sorted list. */\n>>  extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n>>  extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n>> -extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);\n>> +extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds,\n>> +                       struct cmdnames *other_cmds, struct cmdnames *alias_cmds);\n>>\n>>  /*\n>>   * call this to die(), when it is suspected that the user mistyped a\n"},{"id":"235338","messageId":"xmqqk3ci6eun.fsf@gitster.dls.corp.google.com","threadId":"35950","inReplyTo":"CAAkaFLVRP3WF=2hyBo9uxutJ8iLPyBVkiBs=29xN13762r32Bg@mail.gmail.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-02-25T21:51:12Z","receivedAt":"2014-02-25T21:51:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Joel Nothman <joel.nothman@gmail.com> writes:\n\n> arguments to git help. They are also like commands in that it is\n> possible to forget their name, or whether they are defined on a\n> particular workstation, and to hence want a listing.\n\nI did envision that it would be useful for the last case, but then\nthe users would be helped even more if they can get a list of ONLY\naliases, not buried in many standard commands they already know\nabout.\n\nIn other words, I was not fundamentally opposed to *a* way to get a\nlist that includes aliases, but I was not convinced if it is a good\nidea to *change* the output, which people knew would consist of\ncommands but not aliases, to suddenly start including aliases.\n"},{"id":"235342","messageId":"CAAkaFLX49C5CoXcPL9ZBLvNuHnCNg+0QSMfWLzJ0VU_wxOH5zw@mail.gmail.com","threadId":"35950","inReplyTo":"xmqqk3ci6eun.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Joel Nothman","fromEmail":"joel.nothman@gmail.com","sentAt":"2014-02-25T22:32:28Z","receivedAt":"2014-02-25T22:32:28Z","isPatch":true,"sender":{"key":"joel.nothman@gmail.com","avatar":"https://gravatar.com/avatar/8da89a7c58a878272b07d3c16cf8c8cd08e3b1cf287e0b330aadca470cb07608?d=mp&s=160"},"body":"On 26 February 2014 08:51, Junio C Hamano <gitster@pobox.com> wrote:\n> Joel Nothman <joel.nothman@gmail.com> writes:\n>\n>> arguments to git help. They are also like commands in that it is\n>> possible to forget their name, or whether they are defined on a\n>> particular workstation, and to hence want a listing.\n>\n> I did envision that it would be useful for the last case, but then\n> the users would be helped even more if they can get a list of ONLY\n> aliases, not buried in many standard commands they already know\n> about.\n\nThe list is partitioned. It is partitioned already between\ngit-installed commands and others on the path. This patch adds a third\npartition when required. So they *do* see only aliases... after all\nthe commands.\n\nNote also that any command on the path will override an alias with the\nsame name. So in order to list (effective) aliases, you need to\ncalculate the list of commands as well. If someone defines an alias\noverridden by a command, git help -a now makes that apparent by\nexcluding the alias and including the command above it, while `git\nconfig --get-regexp ^alias` does not.\n\n> In other words, I was not fundamentally opposed to *a* way to get a\n> list that includes aliases, but I was not convinced if it is a good\n> idea to *change* the output, which people knew would consist of\n> commands but not aliases, to suddenly start including aliases.\n\nI don't think this will concern most users for whom aliases are\nnon-existent, and hence no section will be shown.\n"},{"id":"235344","messageId":"42F80A3E11EB40DE910D5C71A37AE10C@PhilipOakley","threadId":"35950","inReplyTo":"CAAkaFLVRP3WF=2hyBo9uxutJ8iLPyBVkiBs=29xN13762r32Bg@mail.gmail.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2014-02-25T22:44:37Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Joel Nothman\" <joel.nothman@gmail.com>\n> On 26 February 2014 06:15, Junio C Hamano <gitster@pobox.com> wrote:\n>> Joel Nothman <joel.nothman@gmail.com> writes:\n>>\n>>> Git help --all had listed all git commands, but no configured \n>>> aliases.\n>>> This includes aliases as a separate listing, after commands in the \n>>> main\n>>> git directory and other $PATH directories.\n>>\n>> ... and why is this a good thing?\n>\n> A fair question: I had considered it a conspicuous absence from the\n> list of commands in git help.\n\nSurely one alternative would be to add an --alias or --aliases option to \nthe help command so the user can chose which ones s/he desires to be \nhelped about.\n\nAt least that's the way I did it with the --guides option.\n\n>  After all, aliases are treated like\n> commands for a few purposes: they are executed as commands, they are\n> listed as possible command spelling corrections, and they are valid\n> arguments to git help. They are also like commands in that it is\n> possible to forget their name, or whether they are defined on a\n> particular workstation, and to hence want a listing. A user may also\n> not recall whether they had implemented a particular shortcut as an\n> alias or as a script (one may initially implement a script, and\n> realise an alias is sufficient; one may at first implement an alias\n> and realise it is insufficient, and that a script is needed).\n>\n> In short, for many of the purposes in which one would seek git help\n> -a, there is no reason to *exclude* aliases from a list of commands\n> executed likewise.\n>\n>>>\n>>> Signed-off-by: Joel Nothman <joel.nothman <at> gmail.com>\n>>> ---\n>>>  Documentation/git-help.txt |  4 +--\n>>>  builtin/help.c             |  7 ++---\n>>>  help.c                     | 64 \n>>> +++++++++++++++++++++++++++++++++++-----------\n>>>  help.h                     |  7 ++++-\n>>>  4 files changed, 61 insertions(+), 21 deletions(-)\n>>>\n>>> diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt\n>>> index b21e9d7..c9fe791 100644\n>>> --- a/Documentation/git-help.txt\n>>> +++ b/Documentation/git-help.txt\n>>> @@ -40,8 +40,8 @@ OPTIONS\n>>>  -------\n>>>  -a::\n>>>  --all::\n>>> -     Prints all the available commands on the standard output. This\n>>> -     option overrides any given command or guide name.\n>>> +     Prints all the available commands and aliases on the standard \n>>> output.\n>>> +     This option overrides any given command or guide name.\n>>>\n>>>  -g::\n>>>  --guides::\n>>> diff --git a/builtin/help.c b/builtin/help.c\n>>> index 1fdefeb..d1dfecd 100644\n>>> --- a/builtin/help.c\n>>> +++ b/builtin/help.c\n>>> @@ -38,7 +38,7 @@ static int show_guides = 0;\n>>>  static unsigned int colopts;\n>>>  static enum help_format help_format = HELP_FORMAT_NONE;\n>>>  static struct option builtin_help_options[] = {\n>>> -     OPT_BOOL('a', \"all\", &show_all, N_(\"print all available \n>>> commands\")),\n>>> +     OPT_BOOL('a', \"all\", &show_all, N_(\"print all available \n>>> commands and aliases\")),\n>>>       OPT_BOOL('g', \"guides\", &show_guides, N_(\"print list of useful \n>>> guides\")),\n>>>       OPT_SET_INT('m', \"man\", &help_format, N_(\"show man page\"), \n>>> HELP_FORMAT_MAN),\n>>>       OPT_SET_INT('w', \"web\", &help_format, N_(\"show manual in web \n>>> browser\"),\n>>> @@ -453,6 +453,7 @@ int cmd_help(int argc, const char **argv, const \n>>> char *prefix)\n>>>       int nongit;\n>>>       const char *alias;\n>>>       enum help_format parsed_help_format;\n>>> +     struct cmdnames alias_cmds;\n>>>\n>>>       argc = parse_options(argc, argv, prefix, builtin_help_options,\n>>>                       builtin_help_usage, 0);\n>>> @@ -461,8 +462,8 @@ int cmd_help(int argc, const char **argv, const \n>>> char *prefix)\n>>>       if (show_all) {\n>>>               git_config(git_help_config, NULL);\n>>>               printf(_(\"usage: %s%s\"), _(git_usage_string), \"\\n\\n\");\n>>> -             load_command_list(\"git-\", &main_cmds, &other_cmds);\n>>> -             list_commands(colopts, &main_cmds, &other_cmds);\n>>> +             load_commands_and_aliases(\"git-\", &main_cmds, \n>>> &other_cmds, &alias_cmds);\n>>> +             list_commands(colopts, &main_cmds, &other_cmds, \n>>> &alias_cmds);\n>>>       }\n>>>\n>>>       if (show_guides)\n>>> diff --git a/help.c b/help.c\n>>> index df7d16d..3c14af4 100644\n>>> --- a/help.c\n>>> +++ b/help.c\n>>> @@ -86,7 +86,7 @@ static void pretty_print_string_list(struct \n>>> cmdnames *cmds,\n>>>       int i;\n>>>\n>>>       for (i = 0; i < cmds->cnt; i++)\n>>> -             string_list_append(&list, cmds->names[i]->name);\n>>> +         string_list_append(&list, cmds->names[i]->name);\n>>>       /*\n>>>        * always enable column display, we only consult column.*\n>>>        * about layout strategy and stuff\n>>> @@ -202,8 +202,48 @@ void load_command_list(const char *prefix,\n>>>       exclude_cmds(other_cmds, main_cmds);\n>>>  }\n>>>\n>>> +static struct cmdnames aliases;\n>>> +\n>>> +static void add_cmd_list(struct cmdnames *cmds, struct cmdnames \n>>> *old)\n>>> +{\n>>> +     int i;\n>>> +     ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n>>> +\n>>> +     for (i = 0; i < old->cnt; i++)\n>>> +             cmds->names[cmds->cnt++] = old->names[i];\n>>> +     free(old->names);\n>>> +     old->cnt = 0;\n>>> +     old->names = NULL;\n>>> +}\n>>> +\n>>> +static int load_aliases_cb(const char *var, const char *value, void \n>>> *cb)\n>>> +{\n>>> +     if (starts_with(var, \"alias.\"))\n>>> +             add_cmdname(&aliases, var + 6, strlen(var + 6));\n>>> +     return 0;\n>>> +}\n>>> +\n>>> +void load_commands_and_aliases(const char *prefix,\n>>> +             struct cmdnames *main_cmds,\n>>> +             struct cmdnames *other_cmds,\n>>> +             struct cmdnames *alias_cmds)\n>>> +{\n>>> +     load_command_list(prefix, main_cmds, other_cmds);\n>>> +\n>>> +     /* reuses global aliases from unknown command functionality */\n>>> +     git_config(load_aliases_cb, NULL);\n>>> +\n>>> +     add_cmd_list(alias_cmds, &aliases);\n>>> +     qsort(alias_cmds->names, alias_cmds->cnt,\n>>> +               sizeof(*alias_cmds->names), cmdname_compare);\n>>> +     uniq(alias_cmds);\n>>> +     exclude_cmds(alias_cmds, main_cmds);\n>>> +     exclude_cmds(alias_cmds, other_cmds);\n>>> +}\n>>> +\n>>>  void list_commands(unsigned int colopts,\n>>> -                struct cmdnames *main_cmds, struct cmdnames \n>>> *other_cmds)\n>>> +                struct cmdnames *main_cmds, struct cmdnames \n>>> *other_cmds,\n>>> +                struct cmdnames *alias_cmds)\n>>>  {\n>>>       if (main_cmds->cnt) {\n>>>               const char *exec_path = git_exec_path();\n>>> @@ -219,6 +259,13 @@ void list_commands(unsigned int colopts,\n>>>               pretty_print_string_list(other_cmds, colopts);\n>>>               putchar('\\n');\n>>>       }\n>>> +\n>>> +     if (alias_cmds->cnt) {\n>>> +             printf_ln(_(\"aliases defined in git configuration\"));\n>>> +             putchar('\\n');\n>>> +             pretty_print_string_list(alias_cmds, colopts);\n>>> +             putchar('\\n');\n>>> +     }\n>>>  }\n>>>\n>>>  void list_common_cmds_help(void)\n>>> @@ -248,7 +295,6 @@ int is_in_cmdlist(struct cmdnames *c, const char \n>>> *s)\n>>>  }\n>>>\n>>>  static int autocorrect;\n>>> -static struct cmdnames aliases;\n>>>\n>>>  static int git_unknown_cmd_config(const char *var, const char \n>>> *value, void *cb)\n>>>  {\n>>> @@ -270,18 +316,6 @@ static int levenshtein_compare(const void *p1, \n>>> const void *p2)\n>>>       return l1 != l2 ? l1 - l2 : strcmp(s1, s2);\n>>>  }\n>>>\n>>> -static void add_cmd_list(struct cmdnames *cmds, struct cmdnames \n>>> *old)\n>>> -{\n>>> -     int i;\n>>> -     ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);\n>>> -\n>>> -     for (i = 0; i < old->cnt; i++)\n>>> -             cmds->names[cmds->cnt++] = old->names[i];\n>>> -     free(old->names);\n>>> -     old->cnt = 0;\n>>> -     old->names = NULL;\n>>> -}\n>>> -\n>>>  /* An empirically derived magic number */\n>>>  #define SIMILARITY_FLOOR 7\n>>>  #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)\n>>> diff --git a/help.h b/help.h\n>>> index b21d7c9..3939bc6 100644\n>>> --- a/help.h\n>>> +++ b/help.h\n>>> @@ -21,11 +21,16 @@ extern const char *help_unknown_cmd(const char \n>>> *cmd);\n>>>  extern void load_command_list(const char *prefix,\n>>>                             struct cmdnames *main_cmds,\n>>>                             struct cmdnames *other_cmds);\n>>> +extern void load_commands_and_aliases(const char *prefix,\n>>> +                           struct cmdnames *main_cmds,\n>>> +                           struct cmdnames *other_cmds,\n>>> +                           struct cmdnames *alias_cmds);\n>>>  extern void add_cmdname(struct cmdnames *cmds, const char *name, \n>>> int len);\n>>>  /* Here we require that excludes is a sorted list. */\n>>>  extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames \n>>> *excludes);\n>>>  extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n>>> -extern void list_commands(unsigned int colopts, struct cmdnames \n>>> *main_cmds, struct cmdnames *other_cmds);\n>>> +extern void list_commands(unsigned int colopts, struct cmdnames \n>>> *main_cmds,\n>>> +                       struct cmdnames *other_cmds, struct cmdnames \n>>> *alias_cmds);\n>>>\n>>>  /*\n>>>   * call this to die(), when it is suspected that the user mistyped \n>>> a\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n"},{"id":"235345","messageId":"xmqqmwhe4w27.fsf@gitster.dls.corp.google.com","threadId":"35950","inReplyTo":"1393289315-28982-1-git-send-email-joel.nothman@gmail.com","subject":"Re: [PATCH] help: include list of aliases in git-help --all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-02-25T23:22:24Z","receivedAt":"2014-02-25T23:22:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Joel Nothman <joel.nothman@gmail.com> writes:\n\n> Git help --all had listed all git commands, but no configured aliases.\n> This includes aliases as a separate listing, after commands in the main\n> git directory and other $PATH directories.\n>\n> Signed-off-by: Joel Nothman <joel.nothman <at> gmail.com>\n> ---\n\nThanks.\n\n> diff --git a/help.c b/help.c\n> index df7d16d..3c14af4 100644\n> --- a/help.c\n> +++ b/help.c\n> @@ -86,7 +86,7 @@ static void pretty_print_string_list(struct cmdnames *cmds,\n>  \tint i;\n>  \n>  \tfor (i = 0; i < cmds->cnt; i++)\n> -\t\tstring_list_append(&list, cmds->names[i]->name);\n> +\t    string_list_append(&list, cmds->names[i]->name);\n\nWhy?\n\n> @@ -202,8 +202,48 @@ void load_command_list(const char *prefix,\n>  \texclude_cmds(other_cmds, main_cmds);\n>  }\n>  \n> +static struct cmdnames aliases;\n\nInstead of using a static global variable, perhaps make this an\non-stack variable in load_commands_and_aliases() that is passed as a\ncallback parameter to load_aliases_cb() thru git_config()?\n\n> +static int load_aliases_cb(const char *var, const char *value, void *cb)\n> +{\n\nThat is, cb here is the second parameter you gave to git_config().\n\n>  void list_commands(unsigned int colopts,\n> -\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds)\n> +\t\t   struct cmdnames *main_cmds, struct cmdnames *other_cmds,\n> +\t\t   struct cmdnames *alias_cmds)\n>  {\n>  \tif (main_cmds->cnt) {\n>  \t\tconst char *exec_path = git_exec_path();\n> @@ -219,6 +259,13 @@ void list_commands(unsigned int colopts,\n>  \t\tpretty_print_string_list(other_cmds, colopts);\n>  \t\tputchar('\\n');\n>  \t}\n> +\n> +\tif (alias_cmds->cnt) {\n> +\t\tprintf_ln(_(\"aliases defined in git configuration\"));\n\nThis will not break the use of \"git help -a\" in our completion\nscript, because it ignores anything that does not begin with two SP\nfollowed by alphanumerics.\n\nIt may however break scripts that read from \"help -a\" done by other\npeople that may remove the lines in the output that are known to\nthem as not names of commands (i.e. \"available git commands...\"  and\n\"git commands avaliable elsewhere...\")---they haven't seen this new\nstring and would not know that this line must be skipped.\n\nOther than that, looks reasonably cleanly done.  We'd need a test to\ncover this so that other people will not break it in future patches.\n"}]}