Skip to content

Commit eeaa24b

Browse files
ttaylorrgitster
authored andcommitted
builtin/config: introduce --default
For some use cases, callers of the `git-config(1)` builtin would like to fallback to default values when the variable asked for does not exist. In addition, users would like to use existing type specifiers to ensure that values are parsed correctly when they do exist in the configuration. For example, to fetch a value without a type specifier and fallback to `$fallback`, the following is required: $ git config core.foo || echo "$fallback" This is fine for most values, but can be tricky for difficult-to-express `$fallback`'s, like ANSI color codes. This motivates `--get-color`, which is a one-off exception to the normal type specifier rules wherein a user specifies both the configuration variable and an optional fallback. Both are formatted according to their type specifier, which eases the burden on the user to ensure that values are correctly formatted. This commit (and those following it in this series) aim to eventually replace `--get-color` with a consistent alternative. By introducing `--default`, we allow the `--get-color` action to be promoted to a `--type=color` type specifier, retaining the "fallback" behavior via the `--default` flag introduced in this commit. For example, we aim to replace: $ git config --get-color variable [default] [...] with: $ git config --default default --type=color variable [...] Values filled by `--default` behave exactly as if they were present in the affected configuration file; they will be parsed by type specifiers without the knowledge that they are not themselves present in the configuration. Specifically, this means that the following will work: $ git config --int --default 1M does.not.exist 1048576 In subsequent commits, we will offer `--type=color`, which (in conjunction with `--default`) will be sufficient to replace `--get-color`. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fb0dc3b commit eeaa24b

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

Documentation/git-config.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ Valid `<type>`'s include:
240240
using `--file`, `--global`, etc) and `on` when searching all
241241
config files.
242242

243+
--default <value>::
244+
When using `--get`, and the requested variable is not found, behave as if
245+
<value> were the value assigned to the that variable.
246+
243247
CONFIGURATION
244248
-------------
245249
`pager.config` is only respected when listing configuration, i.e., when

builtin/config.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static char term = '\n';
2626
static int use_global_config, use_system_config, use_local_config;
2727
static struct git_config_source given_config_source;
2828
static int actions, type;
29+
static char *default_value;
2930
static int end_null;
3031
static int respect_includes_opt = -1;
3132
static struct config_options config_options;
@@ -149,6 +150,7 @@ static struct option builtin_config_options[] = {
149150
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
150151
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
151152
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
153+
OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
152154
OPT_END(),
153155
};
154156

@@ -313,6 +315,16 @@ static int get_value(const char *key_, const char *regex_)
313315
config_with_options(collect_config, &values,
314316
&given_config_source, &config_options);
315317

318+
if (!values.nr && default_value) {
319+
struct strbuf *item;
320+
ALLOC_GROW(values.items, values.nr + 1, values.alloc);
321+
item = &values.items[values.nr++];
322+
strbuf_init(item, 0);
323+
if (format_config(item, key_, default_value) < 0)
324+
die(_("failed to format default config value: %s"),
325+
default_value);
326+
}
327+
316328
ret = !values.nr;
317329

318330
for (i = 0; i < values.nr; i++) {
@@ -651,6 +663,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
651663
usage_with_options(builtin_config_usage, builtin_config_options);
652664
}
653665

666+
if (default_value && !(actions & ACTION_GET)) {
667+
error("--default is only applicable to --get");
668+
usage_with_options(builtin_config_usage,
669+
builtin_config_options);
670+
}
671+
654672
if (actions & PAGING_ACTIONS)
655673
setup_auto_pager("config", 1);
656674

t/t1310-config-default.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/sh
2+
3+
test_description='Test git config in different settings (with --default)'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'uses --default when entry missing' '
8+
echo quux >expect &&
9+
git config -f config --default=quux core.foo >actual &&
10+
test_cmp expect actual
11+
'
12+
13+
test_expect_success 'does not use --default when entry present' '
14+
echo bar >expect &&
15+
git -c core.foo=bar config --default=baz core.foo >actual &&
16+
test_cmp expect actual
17+
'
18+
19+
test_expect_success 'canonicalizes --default with appropriate type' '
20+
echo true >expect &&
21+
git config -f config --default=yes --bool core.foo >actual &&
22+
test_cmp expect actual
23+
'
24+
25+
test_expect_success 'dies when --default cannot be parsed' '
26+
test_must_fail git config -f config --type=expiry-date --default=x --get \
27+
not.a.section 2>error &&
28+
test_i18ngrep "failed to format default config value" error
29+
'
30+
31+
test_expect_success 'does not allow --default without --get' '
32+
test_must_fail git config --default=quux --unset a.section >output 2>&1 &&
33+
test_i18ngrep "\-\-default is only applicable to" output
34+
'
35+
36+
test_done

0 commit comments

Comments
 (0)