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>
This commit is contained in:
SZEDER Gábor 2015-08-10 11:46:06 +02:00 committed by Junio C Hamano
parent 77bd3ea9f5
commit 578625fa91
4 changed files with 42 additions and 5 deletions

View File

@ -14,13 +14,13 @@ SYNOPSIS
'git config' [<file-option>] [type] --replace-all name value [value_regex] 'git config' [<file-option>] [type] --replace-all name value [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get name [value_regex] 'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex] 'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex] 'git config' [<file-option>] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL 'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
'git config' [<file-option>] --unset name [value_regex] 'git config' [<file-option>] --unset name [value_regex]
'git config' [<file-option>] --unset-all name [value_regex] 'git config' [<file-option>] --unset-all name [value_regex]
'git config' [<file-option>] --rename-section old_name new_name 'git config' [<file-option>] --rename-section old_name new_name
'git config' [<file-option>] --remove-section name 'git config' [<file-option>] --remove-section name
'git config' [<file-option>] [-z|--null] -l | --list 'git config' [<file-option>] [-z|--null] [--name-only] -l | --list
'git config' [<file-option>] --get-color name [default] 'git config' [<file-option>] --get-color name [default]
'git config' [<file-option>] --get-colorbool name [stdout-is-tty] 'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
'git config' [<file-option>] -e | --edit 'git config' [<file-option>] -e | --edit
@ -159,7 +159,7 @@ See also <<FILES>>.
-l:: -l::
--list:: --list::
List all variables set in config file. List all variables set in config file, along with their values.
--bool:: --bool::
'git config' will ensure that the output is "true" or "false" 'git config' will ensure that the output is "true" or "false"
@ -190,6 +190,10 @@ See also <<FILES>>.
output without getting confused e.g. by values that output without getting confused e.g. by values that
contain line breaks. contain line breaks.
--name-only::
Output only the names of config variables for `--list` or
`--get-regexp`.
--get-colorbool name [stdout-is-tty]:: --get-colorbool name [stdout-is-tty]::
Find the color setting for `name` (e.g. `color.diff`) and output Find the color setting for `name` (e.g. `color.diff`) and output

View File

@ -13,6 +13,7 @@ static char *key;
static regex_t *key_regexp; static regex_t *key_regexp;
static regex_t *regexp; static regex_t *regexp;
static int show_keys; static int show_keys;
static int omit_values;
static int use_key_regexp; static int use_key_regexp;
static int do_all; static int do_all;
static int do_not_match; static int do_not_match;
@ -78,6 +79,7 @@ static struct option builtin_config_options[] = {
OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH), OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
OPT_GROUP(N_("Other")), OPT_GROUP(N_("Other")),
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")), OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")), OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
OPT_END(), OPT_END(),
}; };
@ -91,7 +93,7 @@ static void check_argc(int argc, int min, int max) {
static int show_all_config(const char *key_, const char *value_, void *cb) static int show_all_config(const char *key_, const char *value_, void *cb)
{ {
if (value_) if (!omit_values && value_)
printf("%s%c%s%c", key_, delim, value_, term); printf("%s%c%s%c", key_, delim, value_, term);
else else
printf("%s%c", key_, term); printf("%s%c", key_, term);
@ -117,6 +119,10 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
strbuf_addstr(buf, key_); strbuf_addstr(buf, key_);
must_print_delim = 1; must_print_delim = 1;
} }
if (omit_values) {
strbuf_addch(buf, term);
return 0;
}
if (types == TYPE_INT) if (types == TYPE_INT)
sprintf(value, "%"PRId64, sprintf(value, "%"PRId64,
git_config_int64(key_, value_ ? value_ : "")); git_config_int64(key_, value_ ? value_ : ""));
@ -549,7 +555,11 @@ int cmd_config(int argc, const char **argv, const char *prefix)
default: default:
usage_with_options(builtin_config_usage, builtin_config_options); usage_with_options(builtin_config_usage, builtin_config_options);
} }
if (omit_values &&
!(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
error("--name-only is only applicable to --list or --get-regexp");
usage_with_options(builtin_config_usage, builtin_config_options);
}
if (actions == ACTION_LIST) { if (actions == ACTION_LIST) {
check_argc(argc, 0, 0); check_argc(argc, 0, 0);
if (git_config_with_options(show_all_config, NULL, if (git_config_with_options(show_all_config, NULL,

View File

@ -1887,6 +1887,7 @@ _git_config ()
--get --get-all --get-regexp --get --get-all --get-regexp
--add --unset --unset-all --add --unset --unset-all
--remove-section --rename-section --remove-section --rename-section
--name-only
" "
return return
;; ;;

View File

@ -352,6 +352,18 @@ test_expect_success '--list without repo produces empty output' '
test_cmp expect output test_cmp expect output
' '
cat > expect << EOF
beta.noindent
nextsection.nonewline
123456.a123
version.1.2.3eX.alpha
EOF
test_expect_success '--name-only --list' '
git config --name-only --list >output &&
test_cmp expect output
'
cat > expect << EOF cat > expect << EOF
beta.noindent sillyValue beta.noindent sillyValue
nextsection.nonewline wow2 for me nextsection.nonewline wow2 for me
@ -362,6 +374,16 @@ test_expect_success '--get-regexp' '
test_cmp expect output test_cmp expect output
' '
cat > expect << EOF
beta.noindent
nextsection.nonewline
EOF
test_expect_success '--name-only --get-regexp' '
git config --name-only --get-regexp in >output &&
test_cmp expect output
'
cat > expect << EOF cat > expect << EOF
wow2 for me wow2 for me
wow4 for you wow4 for you