By default we show porcelain, external commands and a couple others
that are also popular. If you are not happy with this list, you can
now customize it. See the big comment block for details.
PS. perhaps I should make aliases a group too, which makes it possible
to _not_ complete aliases by omitting this special group in
$GIT_COMPLETION_CMD_GROUPS
---
contrib/completion/git-completion.bash | 35 ++++++++++++++++++++++++++
git.c | 2 ++
help.c | 33 ++++++++++++++++++++++++
help.h | 1 +
4 files changed, 71 insertions(+)
diff --git a/contrib/completion/git-completion.bash
b/contrib/completion/git-completion.bash
index 908692ea52..0fd29803d5 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -38,6 +38,38 @@
#
# When set to "1", do not include "DWIM" suggestions in git-checkout
# completion (e.g., completing "foo" when "origin/foo" exists).
+#
+# GIT_COMPLETION_CMD_GROUPS
+#
+# When set, "git --list-cmds=$GIT_COMPLETION_CMD_GROUPS" will be
+# used to get the list of completable commands. The default is
+# "mainporcelain,others,list-complete" (in English: all porcelain
+# commands and external ones are included. Certain non-porcelain
+# commands are also marked for completion in command-list.txt).
+# You could for example complete all commands with
+#
+# GIT_COMPLETION_CMD_GROUPS=main,others
+#
+# Or you could go with defaults add some extra commands specified
+# in the configuration variable completion.commands [1] with
+#
+# GIT_COMPLETION_CMD_GROUPS=mainporcelain,others,list-complete,config
+#
+# Or go completely custom group with
+#
+# GIT_COMPLETION_CMD_GROUPS=config
+#
+# Or you could even play with other command categories found in
+# command-list.txt.
+#
+# [1] Note that completion.commands should not be per-repository
+# since the command list is generated once and cached.
+#
+# completion.commands could be used to exclude commands as
+# well. If a command in this list begins with '-', then it
+# will be excluded from the list of commands gathered by the
+# groups specified before "config" in
+# $GIT_COMPLETION_CMD_GROUPS.
case "$COMP_WORDBREAKS" in
*:*) : great ;;
@@ -840,6 +872,9 @@ __git_commands () {
if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
then
printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ elif test -n "$GIT_COMPLETION_CMD_GROUPS"
+ then
+ git --list-cmds="$GIT_COMPLETION_CMD_GROUPS"
else
git --list-cmds=list-mainporcelain,others,list-complete
fi
diff --git a/git.c b/git.c
index 67f3e20ae9..fd08911e11 100644
--- a/git.c
+++ b/git.c
@@ -53,6 +53,8 @@ static int list_cmds(const char *spec)
list_all_main_cmds(&list);
else if (len == 6 && !strncmp(spec, "others", 6))
list_all_other_cmds(&list);
+ else if (len == 6 && !strncmp(spec, "config", 6))
+ list_cmds_by_config(&list);
else if (len > 5 && !strncmp(spec, "list-", 5)) {
struct strbuf sb = STRBUF_INIT;
diff --git a/help.c b/help.c
index 23924dd300..abf87205b2 100644
--- a/help.c
+++ b/help.c
@@ -366,6 +366,39 @@ void list_cmds_by_category(struct string_list *list,
}
}
+void list_cmds_by_config(struct string_list *list)
+{
+ const char *cmd_list;
+
+ /*
+ * There's no actual repository setup at this point (and even
+ * if there is, we don't really care; only global config
+ * matters). If we accidentally set up a repository, it's ok
+ * too since the caller (git --list-cmds=) should exit shortly
+ * anyway.
+ */
+ if (git_config_get_string_const("completion.commands", &cmd_list))
+ return;
+
+ string_list_sort(list);
+ string_list_remove_duplicates(list, 0);
+
+ while (*cmd_list) {
+ struct strbuf sb = STRBUF_INIT;
+ const char *p = strchrnul(cmd_list, ' ');
+
+ strbuf_add(&sb, cmd_list, p - cmd_list);
+ if (*cmd_list == '-')
+ string_list_remove(list, cmd_list + 1, 0);
+ else
+ string_list_insert(list, sb.buf);
+ strbuf_release(&sb);
+ while (*p == ' ')
+ p++;
+ cmd_list = p;
+ }
+}
+
void list_common_guides_help(void)
{
struct category_description catdesc[] = {
diff --git a/help.h b/help.h
index b2293e99be..3b38292a1b 100644
--- a/help.h
+++ b/help.h
@@ -26,6 +26,7 @@ extern void list_all_main_cmds(struct string_list *list);
extern void list_all_other_cmds(struct string_list *list);
extern void list_cmds_by_category(struct string_list *list,
const char *category);
+extern void list_cmds_by_config(struct string_list *list);
extern const char *help_unknown_cmd(const char *cmd);
extern void load_command_list(const char *prefix,
struct cmdnames *main_cmds,
--
2.17.0.705.g3525833791