git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/9] help: add --config to list all available config

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
May 10, 2018, 14:19 UTC
Message-ID
<20180510141927.23590-5-pclouds@gmail.com>
In-Reply-To
<20180510141927.23590-1-pclouds@gmail.com>

Sometimes it helps to list all available config vars so the user can search for something they want. The config man page can also be used but it's harder to search if you want to focus on the variable name, for example.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-help.txt |  5 ++++
 advice.c                   |  9 +++++++
 builtin/branch.c           |  6 +++++
 builtin/clean.c            |  6 +++++
 builtin/commit.c           |  7 ++++++
 builtin/help.c             |  9 +++++++
 diff.c                     |  7 ++++++
 fsck.c                     | 11 +++++++++
 generate-cmdlist.sh        | 20 ++++++++++++++++
 grep.c                     |  7 ++++++
 help.c                     | 48 ++++++++++++++++++++++++++++++++++++++
 help.h                     | 18 ++++++++++++++
 log-tree.c                 |  6 +++++
 13 files changed, 159 insertions(+)
diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt
index a40fc38d8b..83d25d825a 100644
--- a/Documentation/git-help.txt
+++ b/Documentation/git-help.txt
@@ -45,6 +45,11 @@ OPTIONS
 	When used with `--verbose` print description for all recognized
 	commands.
 
+-c::
+--config::
+	List all available configuration variables. This is a short
+	summary of the list in linkgit:git-config[1].
+
 -g::
 --guides::
 	Prints a list of useful guides on the standard output. This
diff --git a/advice.c b/advice.c
index 406efc183b..b211ebc588 100644
--- a/advice.c
+++ b/advice.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "config.h"
+#include "help.h"
 
 int advice_push_update_rejected = 1;
 int advice_push_non_ff_current = 1;
@@ -84,6 +85,14 @@ int git_default_advice_config(const char *var, const char *value)
 	return 0;
 }
 
+void list_advices(const char *prefix)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(advice_config); i++)
+		printf("%s.%s\n", prefix, advice_config[i].name);
+}
+
 int error_resolve_conflict(const char *me)
 {
 	if (!strcmp(me, "cherry-pick"))
diff --git a/builtin/branch.c b/builtin/branch.c
index b41f332589..23bbdcb301 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -22,6 +22,7 @@
 #include "wt-status.h"
 #include "ref-filter.h"
 #include "worktree.h"
+#include "help.h"
 
 static const char * const builtin_branch_usage[] = {
 	N_("git branch [<options>] [-r | -a] [--merged | --no-merged]"),
@@ -67,6 +68,11 @@ static const char *color_branch_slots[] = {
 static struct string_list output = STRING_LIST_INIT_DUP;
 static unsigned int colopts;
 
+void list_color_branch_slots(const char *prefix)
+{
+	PRINT_ARRAY(prefix, color_branch_slots);
+}
+
 static int git_branch_config(const char *var, const char *value, void *cb)
 {
 	const char *slot_name;
diff --git a/builtin/clean.c b/builtin/clean.c
index 0ccd95e693..72cea1537e 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -16,6 +16,7 @@
 #include "column.h"
 #include "color.h"
 #include "pathspec.h"
+#include "help.h"
 
 static int force = -1; /* unset */
 static int interactive;
@@ -91,6 +92,11 @@ struct menu_stuff {
 	void *stuff;
 };
 
+void list_color_interactive_slots(const char *prefix)
+{
+	PRINT_ARRAY(prefix, color_interactive_slots);
+}
+
 static int git_clean_config(const char *var, const char *value, void *cb)
 {
 	const char *slot_name;
diff --git a/builtin/commit.c b/builtin/commit.c
index bee5825bd2..41c3c4f5cd 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -32,6 +32,7 @@
 #include "column.h"
 #include "sequencer.h"
 #include "mailmap.h"
+#include "help.h"
 
 static const char * const builtin_commit_usage[] = {
 	N_("git commit [<options>] [--] <pathspec>..."),
@@ -1194,6 +1195,12 @@ static int parse_status_slot(const char *slot)
 	return LOOKUP_CONFIG(color_status_slots, slot);
 }
 
+void list_color_status_slots(const char *prefix)
+{
+	printf("%s.%s\n", prefix, "added");
+	PRINT_ARRAY(prefix, color_status_slots);
+}
+
 static int git_status_config(const char *k, const char *v, void *cb)
 {
 	struct wt_status *s = cb;
diff --git a/builtin/help.c b/builtin/help.c
index 5727fb5e51..a1153cf473 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -36,6 +36,7 @@ static const char *html_path;
 
 static int show_all = 0;
 static int show_guides = 0;
+static int show_config;
 static int verbose;
 static unsigned int colopts;
 static enum help_format help_format = HELP_FORMAT_NONE;
@@ -44,6 +45,7 @@ static struct option builtin_help_options[] = {
 	OPT_BOOL('a', "all", &show_all, N_("print all available commands")),
 	OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
 	OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
+	OPT_BOOL('c', "config", &show_config, N_("print list recognized config variables")),
 	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"),
 			HELP_FORMAT_WEB),
@@ -443,6 +445,13 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 		list_commands(colopts, &main_cmds, &other_cmds);
 	}
 
+	if (show_config) {
+		setup_pager();
+		list_config_help();
+		printf("\n%s\n", _("'git help config' for more information"));
+		return 0;
+	}
+
 	if (show_guides)
 		list_common_guides_help();
 
diff --git a/diff.c b/diff.c
index 6f781a2c57..5cae59ec1a 100644
--- a/diff.c
+++ b/diff.c
@@ -22,6 +22,7 @@
 #include "argv-array.h"
 #include "graph.h"
 #include "packfile.h"
+#include "help.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -100,6 +101,12 @@ static int parse_diff_color_slot(const char *var)
 	return LOOKUP_CONFIG(color_diff_slots, var);
 }
 
+void list_color_diff_slots(const char *prefix)
+{
+	printf("%s.%s\n", prefix, "plain");
+	PRINT_ARRAY(prefix, color_diff_slots);
+}
+
 static int parse_dirstat_params(struct diff_options *options, const char *params_string,
 				struct strbuf *errmsg)
 {
diff --git a/fsck.c b/fsck.c
index f2534abd44..b9f5e7b3f1 100644
--- a/fsck.c
+++ b/fsck.c
@@ -10,6 +10,7 @@
 #include "utf8.h"
 #include "sha1-array.h"
 #include "decorate.h"
+#include "help.h"
 
 #define FSCK_FATAL -1
 #define FSCK_INFO -2
@@ -118,6 +119,16 @@ static int parse_msg_id(const char *text)
 	return -1;
 }
 
+void list_fsck_msg_ids(const char *prefix)
+{
+	int i;
+
+	prepare_msg_ids();
+	/* TODO: we can do better by producing camelCase names */
+	for (i = 0; i < FSCK_MSG_MAX; i++)
+		printf("%s.%s\n", prefix, msg_id_info[i].downcased);
+}
+
 static int fsck_msg_type(enum fsck_msg_id msg_id,
 	struct fsck_options *options)
 {
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
index 8d6d8b45ce..25d4516f1f 100755
--- a/generate-cmdlist.sh
+++ b/generate-cmdlist.sh
@@ -76,6 +76,24 @@ print_command_list () {
 	echo "};"
 }
 
+print_config_list() {
+	cat <<EOF
+static const char *config_name_list[] = {
+EOF
+	grep '^[a-zA-Z].*\..*::$' Documentation/config.txt |
+	grep -v deprecated |
+	sed 's/::$//; s/,  */\n/g' |
+	sort |
+	while read line
+	do
+		echo "	\"$line\","
+	done
+	cat <<EOF
+	NULL,
+};
+EOF
+}
+
 echo "/* Automatically generated by generate-cmdlist.sh */
 struct cmdname_help {
 	const char *name;
@@ -88,3 +106,5 @@ echo
 define_category_names "$1"
 echo
 print_command_list "$1"
+echo
+print_config_list
diff --git a/grep.c b/grep.c
index 2f7ebe60f6..da6dc9af4f 100644
--- a/grep.c
+++ b/grep.c
@@ -7,6 +7,7 @@
 #include "diffcore.h"
 #include "commit.h"
 #include "quote.h"
+#include "help.h"
 
 static int grep_source_load(struct grep_source *gs);
 static int grep_source_is_binary(struct grep_source *gs);
@@ -133,6 +134,12 @@ int grep_config(const char *var, const char *value, void *cb)
 	return 0;
 }
 
+void list_color_grep_slots(const char *prefix)
+{
+	printf("%s.%s\n", prefix, "match");
+	PRINT_ARRAY(prefix, color_grep_slots);
+}
+
 /*
  * Initialize one instance of grep_opt and copy the
  * default values from the template we read the configuration
diff --git a/help.c b/help.c
index abf87205b2..b10c8b0230 100644
--- a/help.c
+++ b/help.c
@@ -409,6 +409,54 @@ void list_common_guides_help(void)
 	putchar('\n');
 }
 
+struct slot_expansion {
+	const char *prefix;
+	const char *placeholder;
+	void (*fn)(const char *prefix);
+	int found;
+};
+
+void list_config_help(void)
+{
+	struct slot_expansion slot_expansions[] = {
+		{ "advice", "*", list_advices },
+		{ "color.branch", "<slot>", list_color_branch_slots },
+		{ "color.decorate", "<slot>", list_color_decorate_slots },
+		{ "color.diff", "<slot>", list_color_diff_slots },
+		{ "color.grep", "<slot>", list_color_grep_slots },
+		{ "color.interactive", "<slot>", list_color_interactive_slots },
+		{ "color.status", "<slot>", list_color_status_slots },
+		{ "fsck", "<msg-id>", list_fsck_msg_ids },
+		{ "receive.fsck", "<msg-id>", list_fsck_msg_ids },
+		{ NULL, NULL, NULL }
+	};
+	const char **p;
+	struct slot_expansion *e;
+
+	for (p = config_name_list; *p; p++) {
+		const char *var = *p;
+
+		for (e = slot_expansions; e->prefix; e++) {
+			struct strbuf sb = STRBUF_INIT;
+
+			strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
+			if (strcasecmp(var, sb.buf))
+				continue;
+			e->fn(e->prefix);
+			strbuf_release(&sb);
+			e->found++;
+			break;
+		}
+		if (!e->prefix)
+			puts(var);
+	}
+
+	for (e = slot_expansions; e->prefix; e++)
+		if (!e->found)
+			BUG("slot_expansion %s.%s is not used",
+			    e->prefix, e->placeholder);
+}
+
 void list_all_cmds_help(void)
 {
 	print_cmd_by_category(main_categories);
diff --git a/help.h b/help.h
index 3b38292a1b..d7d1409718 100644
--- a/help.h
+++ b/help.h
@@ -21,6 +21,7 @@ static inline void mput_char(char c, unsigned int num)
 extern void list_common_cmds_help(void);
 extern void list_all_cmds_help(void);
 extern void list_common_guides_help(void);
+extern void list_config_help(void);
 
 extern void list_all_main_cmds(struct string_list *list);
 extern void list_all_other_cmds(struct string_list *list);
@@ -42,4 +43,21 @@ extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, stru
  * ref to the command, to give suggested "correct" refs.
  */
 extern void help_unknown_ref(const char *ref, const char *cmd, const char *error);
+
+/* These are actually scattered over many C files */
+#define PRINT_ARRAY(prefix, array)  {					\
+		int i;							\
+		for (i = 0; i < ARRAY_SIZE(array); i++)			\
+			if (array[i])					\
+				printf("%s.%s\n", prefix, array[i]);	\
+	}
+void list_advices(const char *prefix);
+void list_color_branch_slots(const char *prefix);
+void list_color_decorate_slots(const char *prefix);
+void list_color_diff_slots(const char *prefix);
+void list_color_grep_slots(const char *prefix);
+void list_color_interactive_slots(const char *prefix);
+void list_color_status_slots(const char *prefix);
+void list_fsck_msg_ids(const char *prefix);
+
 #endif /* HELP_H */
diff --git a/log-tree.c b/log-tree.c
index 093efb477e..19cfebd231 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -12,6 +12,7 @@
 #include "gpg-interface.h"
 #include "sequencer.h"
 #include "line-log.h"
+#include "help.h"
 
 static struct decoration name_decoration = { "object names" };
 static int decoration_loaded;
@@ -42,6 +43,11 @@ static const char *decorate_get_color(int decorate_use_color, enum decoration_ty
 	return "";
 }
 
+void list_color_decorate_slots(const char *prefix)
+{
+	PRINT_ARRAY(prefix, color_decorate_slots);
+}
+
 int parse_decorate_color_config(const char *var, const char *slot_name, const char *value)
 {
 	int slot = LOOKUP_CONFIG(color_decorate_slots, slot_name);
-- 
2.17.0.705.g3525833791
Previous: Nguyễn Thái Ngọc DuyNext: Eric Sunshine
Message 16 of 36 in “completion: avoid hard coding config var list”
  1. 0/9 completion: avoid hard coding config var listNguyễn Thái Ngọc Duy, May 10, 2018
  2. 1/9 Add and use generic name->id mapping code for color slot parsingNguyễn Thái Ngọc Duy, May 10, 2018
  3. Stefan BellerMay 10, 2018
  4. Duy NguyenMay 11, 2018
  5. 3/9 fsck: factor out msg_id_info[] lazy initialization codeNguyễn Thái Ngọc Duy, May 10, 2018
  6. Eric SunshineMay 11, 2018
  7. 2/9 grep: keep all colors in an arrayNguyễn Thái Ngọc Duy, May 10, 2018
  8. 8/9 completion: support case-insensitive config vars just a bitNguyễn Thái Ngọc Duy, May 10, 2018
  9. SZEDER GáborMay 20, 2018
  10. 7/9 completion: drop the hard coded list of config varsNguyễn Thái Ngọc Duy, May 10, 2018
  11. Eric SunshineMay 11, 2018
  12. SZEDER GáborMay 20, 2018
  13. 6/9 am: move advice.amWorkDir parsing back to advice.cNguyễn Thái Ngọc Duy, May 10, 2018
  14. Eric SunshineMay 11, 2018
  15. 9/9 log-tree: allow to customize 'grafted' colorNguyễn Thái Ngọc Duy, May 10, 2018
  16. 4/9 help: add --config to list all available configNguyễn Thái Ngọc Duy, May 10, 2018
  17. Eric SunshineMay 11, 2018
  18. 5/9 advice: keep config name in camelCase in advice_config[]Nguyễn Thái Ngọc Duy, May 10, 2018
  19. Duy NguyenMay 10, 2018
  20. Junio C HamanoMay 11, 2018
  21. Duy NguyenMay 11, 2018
  22. 00/11 completion: avoid hard coding config var listNguyễn Thái Ngọc Duy, May 26, 2018
  23. 01/11 Add and use generic name->id mapping code for color slot parsingNguyễn Thái Ngọc Duy, May 26, 2018
  24. Stefan BellerMay 29, 2018
  25. 04/11 help: add --config to list all available configNguyễn Thái Ngọc Duy, May 26, 2018
  26. Eric SunshineMay 27, 2018
  27. 09/11 completion: keep other config var completion in camelCaseNguyễn Thái Ngọc Duy, May 26, 2018
  28. 07/11 am: move advice.amWorkDir parsing back to advice.cNguyễn Thái Ngọc Duy, May 26, 2018
  29. 11/11 log-tree: allow to customize 'grafted' colorNguyễn Thái Ngọc Duy, May 26, 2018
  30. 12/11 completion: complete general config vars in two stepsNguyễn Thái Ngọc Duy, May 27, 2018
  31. 10/11 completion: support case-insensitive config varsNguyễn Thái Ngọc Duy, May 26, 2018
  32. 03/11 fsck: factor out msg_id_info[] lazy initialization codeNguyễn Thái Ngọc Duy, May 26, 2018
  33. 08/11 completion: drop the hard coded list of config varsNguyễn Thái Ngọc Duy, May 26, 2018
  34. 02/11 grep: keep all colors in an arrayNguyễn Thái Ngọc Duy, May 26, 2018
  35. 06/11 advice: keep config name in camelCase in advice_config[]Nguyễn Thái Ngọc Duy, May 26, 2018
  36. 05/11 fsck: produce camelCase config key namesNguyễn Thái Ngọc Duy, May 26, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.