Skip to content

Commit fc9dfda

Browse files
committed
Merge branch 'sg/config-name-only'
"git config --list" output was hard to parse when values consist of multiple lines. "--name-only" option is added to help this. * sg/config-name-only: get_urlmatch: avoid useless strbuf write format_config: simplify buffer handling format_config: don't init strbuf config: restructure format_config() for better control flow completion: list variable names reliably with 'git config --name-only' config: add '--name-only' option to list only variable names
2 parents aecce6d + a92330d commit fc9dfda

File tree

4 files changed

+74
-60
lines changed

4 files changed

+74
-60
lines changed

Documentation/git-config.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ SYNOPSIS
1414
'git config' [<file-option>] [type] --replace-all name value [value_regex]
1515
'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
1616
'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]
1818
'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
1919
'git config' [<file-option>] --unset name [value_regex]
2020
'git config' [<file-option>] --unset-all name [value_regex]
2121
'git config' [<file-option>] --rename-section old_name new_name
2222
'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
2424
'git config' [<file-option>] --get-color name [default]
2525
'git config' [<file-option>] --get-colorbool name [stdout-is-tty]
2626
'git config' [<file-option>] -e | --edit
@@ -159,7 +159,7 @@ See also <<FILES>>.
159159

160160
-l::
161161
--list::
162-
List all variables set in config file.
162+
List all variables set in config file, along with their values.
163163

164164
--bool::
165165
'git config' will ensure that the output is "true" or "false"
@@ -190,6 +190,10 @@ See also <<FILES>>.
190190
output without getting confused e.g. by values that
191191
contain line breaks.
192192

193+
--name-only::
194+
Output only the names of config variables for `--list` or
195+
`--get-regexp`.
196+
193197
--get-colorbool name [stdout-is-tty]::
194198

195199
Find the color setting for `name` (e.g. `color.diff`) and output

builtin/config.c

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ static char *key;
1313
static regex_t *key_regexp;
1414
static regex_t *regexp;
1515
static int show_keys;
16+
static int omit_values;
1617
static int use_key_regexp;
1718
static int do_all;
1819
static int do_not_match;
@@ -78,6 +79,7 @@ static struct option builtin_config_options[] = {
7879
OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
7980
OPT_GROUP(N_("Other")),
8081
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")),
8183
OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
8284
OPT_END(),
8385
};
@@ -91,7 +93,7 @@ static void check_argc(int argc, int min, int max) {
9193

9294
static int show_all_config(const char *key_, const char *value_, void *cb)
9395
{
94-
if (value_)
96+
if (!omit_values && value_)
9597
printf("%s%c%s%c", key_, delim, value_, term);
9698
else
9799
printf("%s%c", key_, term);
@@ -106,48 +108,40 @@ struct strbuf_list {
106108

107109
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
108110
{
109-
int must_free_vptr = 0;
110-
int must_print_delim = 0;
111-
char value[256];
112-
const char *vptr = value;
113-
114-
strbuf_init(buf, 0);
115-
116-
if (show_keys) {
111+
if (show_keys)
117112
strbuf_addstr(buf, key_);
118-
must_print_delim = 1;
119-
}
120-
if (types == TYPE_INT)
121-
sprintf(value, "%"PRId64,
122-
git_config_int64(key_, value_ ? value_ : ""));
123-
else if (types == TYPE_BOOL)
124-
vptr = git_config_bool(key_, value_) ? "true" : "false";
125-
else if (types == TYPE_BOOL_OR_INT) {
126-
int is_bool, v;
127-
v = git_config_bool_or_int(key_, value_, &is_bool);
128-
if (is_bool)
129-
vptr = v ? "true" : "false";
130-
else
131-
sprintf(value, "%d", v);
132-
} else if (types == TYPE_PATH) {
133-
if (git_config_pathname(&vptr, key_, value_) < 0)
134-
return -1;
135-
must_free_vptr = 1;
136-
} else if (value_) {
137-
vptr = value_;
138-
} else {
139-
/* Just show the key name */
140-
vptr = "";
141-
must_print_delim = 0;
142-
}
113+
if (!omit_values) {
114+
if (show_keys)
115+
strbuf_addch(buf, key_delim);
143116

144-
if (must_print_delim)
145-
strbuf_addch(buf, key_delim);
146-
strbuf_addstr(buf, vptr);
117+
if (types == TYPE_INT)
118+
strbuf_addf(buf, "%"PRId64,
119+
git_config_int64(key_, value_ ? value_ : ""));
120+
else if (types == TYPE_BOOL)
121+
strbuf_addstr(buf, git_config_bool(key_, value_) ?
122+
"true" : "false");
123+
else if (types == TYPE_BOOL_OR_INT) {
124+
int is_bool, v;
125+
v = git_config_bool_or_int(key_, value_, &is_bool);
126+
if (is_bool)
127+
strbuf_addstr(buf, v ? "true" : "false");
128+
else
129+
strbuf_addf(buf, "%d", v);
130+
} else if (types == TYPE_PATH) {
131+
const char *v;
132+
if (git_config_pathname(&v, key_, value_) < 0)
133+
return -1;
134+
strbuf_addstr(buf, v);
135+
free((char *)v);
136+
} else if (value_) {
137+
strbuf_addstr(buf, value_);
138+
} else {
139+
/* Just show the key name; back out delimiter */
140+
if (show_keys)
141+
strbuf_setlen(buf, buf->len - 1);
142+
}
143+
}
147144
strbuf_addch(buf, term);
148-
149-
if (must_free_vptr)
150-
free((char *)vptr);
151145
return 0;
152146
}
153147

@@ -164,6 +158,7 @@ static int collect_config(const char *key_, const char *value_, void *cb)
164158
return 0;
165159

166160
ALLOC_GROW(values->items, values->nr + 1, values->alloc);
161+
strbuf_init(&values->items[values->nr], 0);
167162

168163
return format_config(&values->items[values->nr++], key_, value_);
169164
}
@@ -430,14 +425,11 @@ static int get_urlmatch(const char *var, const char *url)
430425

431426
for_each_string_list_item(item, &values) {
432427
struct urlmatch_current_candidate_value *matched = item->util;
433-
struct strbuf key = STRBUF_INIT;
434428
struct strbuf buf = STRBUF_INIT;
435429

436-
strbuf_addstr(&key, item->string);
437-
format_config(&buf, key.buf,
430+
format_config(&buf, item->string,
438431
matched->value_is_null ? NULL : matched->value.buf);
439432
fwrite(buf.buf, 1, buf.len, stdout);
440-
strbuf_release(&key);
441433
strbuf_release(&buf);
442434

443435
strbuf_release(&matched->value);
@@ -549,7 +541,11 @@ int cmd_config(int argc, const char **argv, const char *prefix)
549541
default:
550542
usage_with_options(builtin_config_usage, builtin_config_options);
551543
}
552-
544+
if (omit_values &&
545+
!(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
546+
error("--name-only is only applicable to --list or --get-regexp");
547+
usage_with_options(builtin_config_usage, builtin_config_options);
548+
}
553549
if (actions == ACTION_LIST) {
554550
check_argc(argc, 0, 0);
555551
if (git_config_with_options(show_all_config, NULL,

contrib/completion/git-completion.bash

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,8 @@ __git_compute_porcelain_commands ()
744744
__git_get_config_variables ()
745745
{
746746
local section="$1" i IFS=$'\n'
747-
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "^$section\..*" 2>/dev/null); do
748-
i="${i#$section.}"
749-
echo "${i/ */}"
747+
for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do
748+
echo "${i#$section.}"
750749
done
751750
}
752751

@@ -1777,15 +1776,7 @@ __git_config_get_set_variables ()
17771776
c=$((--c))
17781777
done
17791778

1780-
git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1781-
while read -r line
1782-
do
1783-
case "$line" in
1784-
*.*=*)
1785-
echo "${line/=*/}"
1786-
;;
1787-
esac
1788-
done
1779+
git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null
17891780
}
17901781

17911782
_git_config ()
@@ -1890,6 +1881,7 @@ _git_config ()
18901881
--get --get-all --get-regexp
18911882
--add --unset --unset-all
18921883
--remove-section --rename-section
1884+
--name-only
18931885
"
18941886
return
18951887
;;

t/t1300-repo-config.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,18 @@ test_expect_success '--list without repo produces empty output' '
352352
test_cmp expect output
353353
'
354354

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+
355367
cat > expect << EOF
356368
beta.noindent sillyValue
357369
nextsection.nonewline wow2 for me
@@ -362,6 +374,16 @@ test_expect_success '--get-regexp' '
362374
test_cmp expect output
363375
'
364376

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+
365387
cat > expect << EOF
366388
wow2 for me
367389
wow4 for you

0 commit comments

Comments
 (0)