Instead of parsing "git help -a" output, which is tricky to get right,
less elegant and also slow, make git provide the list in
machine-friendly form.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 contrib/completion/git-completion.bash |  2 +-
 git.c                                  |  2 ++
 help.c                                 | 18 ++++++++++++++++++
 help.h                                 |  1 +
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 3556838759..a5f13ade20 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -839,7 +839,7 @@ __git_commands () {
        then
                printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}"
        else
-               git help -a|egrep '^  [a-zA-Z0-9]'
+               git --list-cmds=all
        fi
 }
 
diff --git a/git.c b/git.c
index a46263306d..fa6e542d06 100644
--- a/git.c
+++ b/git.c
@@ -229,6 +229,8 @@ static int handle_options(const char ***argv, int *argc, 
int *envchanged)
                                list_builtins(0, '\n');
                        else if (!strcmp(cmd, "parseopt"))
                                list_builtins(NO_PARSEOPT, ' ');
+                       else if (!strcmp(cmd, "all"))
+                               list_all_cmds();
                        else
                                die("unsupported command listing type '%s'", 
cmd);
                        commands_listed++;
diff --git a/help.c b/help.c
index 5b4a2f1b4f..217864999e 100644
--- a/help.c
+++ b/help.c
@@ -287,6 +287,24 @@ void list_common_cmds_help(void)
        print_cmd_by_category(common_categories);
 }
 
+void list_all_cmds(void)
+{
+       struct cmdnames main_cmds, other_cmds;
+       int i;
+
+       memset(&main_cmds, 0, sizeof(main_cmds));
+       memset(&other_cmds, 0, sizeof(other_cmds));
+       load_command_list("git-", &main_cmds, &other_cmds);
+
+       for (i = 0; i < main_cmds.cnt; i++)
+               puts(main_cmds.names[i]->name);
+       for (i = 0; i < other_cmds.cnt; i++)
+               puts(other_cmds.names[i]->name);
+
+       clean_cmdnames(&main_cmds);
+       clean_cmdnames(&other_cmds);
+}
+
 int is_in_cmdlist(struct cmdnames *c, const char *s)
 {
        int i;
diff --git a/help.h b/help.h
index b21d7c94e8..0bf29f8dc5 100644
--- a/help.h
+++ b/help.h
@@ -17,6 +17,7 @@ static inline void mput_char(char c, unsigned int num)
 }
 
 extern void list_common_cmds_help(void);
+extern void list_all_cmds(void);
 extern const char *help_unknown_cmd(const char *cmd);
 extern void load_command_list(const char *prefix,
                              struct cmdnames *main_cmds,
-- 
2.17.0.519.gb89679a4aa

Reply via email to