config: add '--name-only' option to list only variable names

'git config' can only show values or name-value pairs, so if a shell script needs the names of set config variables it has to run 'git config --list' or '--get-regexp' and parse the output to separate config variable names from their values. However, such a parsing can't cope with multi-line values. Though 'git config' can produce null-terminated output for newline-safe parsing, that's of no use in such a case, becase shells can't cope with null characters. Even our own bash completion script suffers from these issues. Help the completion script, and shell scripts in general, by introducing the '--name-only' option to modify the output of '--list' and '--get-regexp' to list only the names of config variables, so they don't have to perform error-prone post processing to separate variable names from their values anymore. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

SZEDER Gábor committed Aug 10, 2015 at 11:46 UTC 578625fa918922713a2ecce2b06611e4566778f5
4 files changed +42 -5
Documentation/git-config.txt
+7 -3
@@ -14,13 +14,13 @@ SYNOPSIS
14 'git config' [<file-option>] [type] --replace-all name value [value_regex]
15 'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
16 'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
17 -'git config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex]
17 +'git config' [<file-option>] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
18 'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
19 'git config' [<file-option>] --unset name [value_regex]
20 'git config' [<file-option>] --unset-all name [value_regex]
21 'git config' [<file-option>] --rename-section old_name new_name
22 'git config' [<file-option>] --remove-section name
23 -'git config' [<file-option>] [-z|--null] -l | --list
23 +'git config' [<file-option>] [-z|--null] [--name-only] -l | --list
24 'git config' [<file-option>] --get-color name [default]
25 'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
26 'git config' [<file-option>] -e | --edit
@@ -159,7 +159,7 @@ See also <<FILES>>.
159
160 -l::
161 --list::
162 - List all variables set in config file.
162 + List all variables set in config file, along with their values.
163
164 --bool::
165 'git config' will ensure that the output is "true" or "false"
@@ -190,6 +190,10 @@ See also <<FILES>>.
190 output without getting confused e.g. by values that
191 contain line breaks.
192
193 +--name-only::
194 + Output only the names of config variables for `--list` or
195 + `--get-regexp`.
196 +
197 --get-colorbool name [stdout-is-tty]::
198
199 Find the color setting for `name` (e.g. `color.diff`) and output
builtin/config.c
+12 -2
@@ -13,6 +13,7 @@ static char *key;
13 static regex_t *key_regexp;
14 static regex_t *regexp;
15 static int show_keys;
16 +static int omit_values;
17 static int use_key_regexp;
18 static int do_all;
19 static int do_not_match;
@@ -78,6 +79,7 @@ static struct option builtin_config_options[] = {
79 OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
80 OPT_GROUP(N_("Other")),
81 OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
82 + OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
83 OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
84 OPT_END(),
85 };
@@ -91,7 +93,7 @@ static void check_argc(int argc, int min, int max) {
93
94 static int show_all_config(const char *key_, const char *value_, void *cb)
95 {
94 - if (value_)
96 + if (!omit_values && value_)
97 printf("%s%c%s%c", key_, delim, value_, term);
98 else
99 printf("%s%c", key_, term);
@@ -117,6 +119,10 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
119 strbuf_addstr(buf, key_);
120 must_print_delim = 1;
121 }
122 + if (omit_values) {
123 + strbuf_addch(buf, term);
124 + return 0;
125 + }
126 if (types == TYPE_INT)
127 sprintf(value, "%"PRId64,
128 git_config_int64(key_, value_ ? value_ : ""));
@@ -549,7 +555,11 @@ int cmd_config(int argc, const char **argv, const char *prefix)
555 default:
556 usage_with_options(builtin_config_usage, builtin_config_options);
557 }
552 -
558 + if (omit_values &&
559 + !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
560 + error("--name-only is only applicable to --list or --get-regexp");
561 + usage_with_options(builtin_config_usage, builtin_config_options);
562 + }
563 if (actions == ACTION_LIST) {
564 check_argc(argc, 0, 0);
565 if (git_config_with_options(show_all_config, NULL,
contrib/completion/git-completion.bash
+1
@@ -1887,6 +1887,7 @@ _git_config ()
1887 --get --get-all --get-regexp
1888 --add --unset --unset-all
1889 --remove-section --rename-section
1890 + --name-only
1891 "
1892 return
1893 ;;
t/t1300-repo-config.sh
+22
@@ -352,6 +352,18 @@ test_expect_success '--list without repo produces empty output' '
352 test_cmp expect output
353 '
354
355 +cat > expect << EOF
356 +beta.noindent
357 +nextsection.nonewline
358 +123456.a123
359 +version.1.2.3eX.alpha
360 +EOF
361 +
362 +test_expect_success '--name-only --list' '
363 + git config --name-only --list >output &&
364 + test_cmp expect output
365 +'
366 +
367 cat > expect << EOF
368 beta.noindent sillyValue
369 nextsection.nonewline wow2 for me
@@ -362,6 +374,16 @@ test_expect_success '--get-regexp' '
374 test_cmp expect output
375 '
376
377 +cat > expect << EOF
378 +beta.noindent
379 +nextsection.nonewline
380 +EOF
381 +
382 +test_expect_success '--name-only --get-regexp' '
383 + git config --name-only --get-regexp in >output &&
384 + test_cmp expect output
385 +'
386 +
387 cat > expect << EOF
388 wow2 for me
389 wow4 for you