Skip to content

Commit 7acdd6f

Browse files
committed
git-config: collect values instead of immediately printing
This is a refactor that will allow us to more easily tweak the behavior for multi-valued variables, and it will ultimately allow us to remove a lot git-config's custom code in favor of the regular git_config code. It does mean we're no longer streaming, and we're storing more in memory for the --get-all case, but in practice it is a tiny amount of data, and the results are instantaneous. Signed-off-by: Jeff King <[email protected]>
1 parent 97ed50f commit 7acdd6f

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

builtin/config.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ static int show_keys;
1515
static int use_key_regexp;
1616
static int do_all;
1717
static int do_not_match;
18-
static int seen;
1918
static char delim = '=';
2019
static char key_delim = ' ';
2120
static char term = '\n';
@@ -95,8 +94,16 @@ static int show_all_config(const char *key_, const char *value_, void *cb)
9594
return 0;
9695
}
9796

98-
static int show_config(const char *key_, const char *value_, void *cb)
97+
struct strbuf_list {
98+
struct strbuf *items;
99+
int nr;
100+
int alloc;
101+
};
102+
103+
static int collect_config(const char *key_, const char *value_, void *cb)
99104
{
105+
struct strbuf_list *values = cb;
106+
struct strbuf *buf;
100107
char value[256];
101108
const char *vptr = value;
102109
int must_free_vptr = 0;
@@ -111,11 +118,15 @@ static int show_config(const char *key_, const char *value_, void *cb)
111118
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
112119
return 0;
113120

121+
ALLOC_GROW(values->items, values->nr + 1, values->alloc);
122+
buf = &values->items[values->nr++];
123+
strbuf_init(buf, 0);
124+
114125
if (show_keys) {
115-
printf("%s", key_);
126+
strbuf_addstr(buf, key_);
116127
must_print_delim = 1;
117128
}
118-
if (seen && !do_all)
129+
if (values->nr > 1 && !do_all)
119130
dup_error = 1;
120131
if (types == TYPE_INT)
121132
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
@@ -138,15 +149,15 @@ static int show_config(const char *key_, const char *value_, void *cb)
138149
vptr = "";
139150
must_print_delim = 0;
140151
}
141-
seen++;
142152
if (dup_error) {
143153
error("More than one value for the key %s: %s",
144154
key_, vptr);
145155
}
146156
else {
147157
if (must_print_delim)
148-
printf("%c", key_delim);
149-
printf("%s%c", vptr, term);
158+
strbuf_addch(buf, key_delim);
159+
strbuf_addstr(buf, vptr);
160+
strbuf_addch(buf, term);
150161
}
151162
if (must_free_vptr)
152163
/* If vptr must be freed, it's a pointer to a
@@ -166,6 +177,8 @@ static int get_value(const char *key_, const char *regex_)
166177
struct config_include_data inc = CONFIG_INCLUDE_INIT;
167178
config_fn_t fn;
168179
void *data;
180+
struct strbuf_list values = {0};
181+
int i;
169182

170183
local = given_config_file;
171184
if (!local) {
@@ -223,8 +236,8 @@ static int get_value(const char *key_, const char *regex_)
223236
}
224237
}
225238

226-
fn = show_config;
227-
data = NULL;
239+
fn = collect_config;
240+
data = &values;
228241
if (respect_includes) {
229242
inc.fn = fn;
230243
inc.data = data;
@@ -241,19 +254,26 @@ static int get_value(const char *key_, const char *regex_)
241254
if (do_all)
242255
git_config_from_file(fn, local, data);
243256
git_config_from_parameters(fn, data);
244-
if (!do_all && !seen)
257+
if (!do_all && !values.nr)
245258
git_config_from_file(fn, local, data);
246-
if (!do_all && !seen && global)
259+
if (!do_all && !values.nr && global)
247260
git_config_from_file(fn, global, data);
248-
if (!do_all && !seen && xdg)
261+
if (!do_all && !values.nr && xdg)
249262
git_config_from_file(fn, xdg, data);
250-
if (!do_all && !seen && system_wide)
263+
if (!do_all && !values.nr && system_wide)
251264
git_config_from_file(fn, system_wide, data);
252265

253266
if (do_all)
254-
ret = !seen;
267+
ret = !values.nr;
255268
else
256-
ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
269+
ret = (values.nr == 1) ? 0 : values.nr > 1 ? 2 : 1;
270+
271+
for (i = 0; i < values.nr; i++) {
272+
struct strbuf *buf = values.items + i;
273+
fwrite(buf->buf, 1, buf->len, stdout);
274+
strbuf_release(buf);
275+
}
276+
free(values.items);
257277

258278
free_strings:
259279
free(repo_config);

0 commit comments

Comments
 (0)