Web lists-archives.com

[PATCH 1/4] builtin/config: introduce `--default`




In an aim to replace:

  $ git config --get-color slot [default] [...]

with:

  $ git config --default default --color slot [...]

introduce `--defualt` to behave as if the given default were present and
assigned to slot in the case that that slot does not exist.

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
configuraion.

Specifically, this means that the following will work:

  $ git config --int --default 1M does.not.exist
  1048576

In subsequent commits, we will offer `--color`, which (in conjunction
with `--default`) will be sufficient to replace `--get-color`.

Signed-off-by: Taylor Blau <me@xxxxxxxxxxxx>
---
 Documentation/git-config.txt |   4 ++
 builtin/config.c             |  19 +++++++
 t/t1310-config-default.sh    | 119 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100755 t/t1310-config-default.sh

diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 14da5fc15..390b49831 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -233,6 +233,10 @@ See also <<FILES>>.
 	using `--file`, `--global`, etc) and `on` when searching all
 	config files.
 
+--default value::
+  When using `--get`, `--get-all`, and `--get-regexp`, behave as
+  if value were the value assigned to the given slot.
+
 [[FILES]]
 FILES
 -----
diff --git a/builtin/config.c b/builtin/config.c
index ab5f95476..76edefc07 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -26,6 +26,7 @@ static char term = '\n';
 static int use_global_config, use_system_config, use_local_config;
 static struct git_config_source given_config_source;
 static int actions, types;
+static char *default_value;
 static int end_null;
 static int respect_includes_opt = -1;
 static struct config_options config_options;
@@ -87,6 +88,7 @@ static struct option builtin_config_options[] = {
 	OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
 	OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
 	OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
+	OPT_STRING(0, "default", &default_value, N_("value"), N_("use default value with missing entry")),
 	OPT_END(),
 };
 
@@ -251,6 +253,16 @@ static int get_value(const char *key_, const char *regex_)
 	config_with_options(collect_config, &values,
 			    &given_config_source, &config_options);
 
+	if (!values.nr && default_value) {
+		struct strbuf *item;
+
+		ALLOC_GROW(values.items, values.nr + 1, values.alloc);
+		item = &values.items[values.nr++];
+		if (format_config(item, key_, default_value) < 0) {
+			values.nr = 0;
+		}
+	}
+
 	ret = !values.nr;
 
 	for (i = 0; i < values.nr; i++) {
@@ -594,6 +606,13 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		usage_with_options(builtin_config_usage, builtin_config_options);
 	}
 
+	if (default_value && !(actions &
+		(ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP))) {
+		error("--default is only applicable to --get, --get-all, "
+			"and --get-regexp.");
+		usage_with_options(builtin_config_usage, builtin_config_options);
+	}
+
 	if (actions == ACTION_LIST) {
 		check_argc(argc, 0, 0);
 		if (config_with_options(show_all_config, NULL,
diff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh
new file mode 100755
index 000000000..57fe63295
--- /dev/null
+++ b/t/t1310-config-default.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+test_description='Test git config in different settings (with --default)'
+
+. ./test-lib.sh
+
+test_expect_success 'clear default config' '
+	rm -f .git/config
+'
+
+test_expect_success 'uses default when missing entry' '
+	echo quux >expect &&
+	git config --default quux core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'uses entry when available' '
+	echo bar >expect &&
+	git config --add core.foo bar &&
+	git config --default baz core.foo >actual &&
+	git config --unset core.foo &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshals default value as bool' '
+	echo true >expect &&
+	git config --default true --bool core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshals default value as int' '
+	echo 810 >expect &&
+	git config --default 810 --int core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshals default value as int (storage unit)' '
+	echo 1048576 >expect &&
+	git config --default 1M --int core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshals default value as bool-or-int' '
+	echo "1
+true" >expect &&
+	git config --default 1 --bool-or-int core.foo >actual &&
+	git config --default true --bool-or-int core.foo >>actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshal default value as path' '
+	echo /path/to/file >expect &&
+	git config --default /path/to/file --path core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshal default value as expiry-date' '
+	echo 0 >expect &&
+	git config --default never --expiry-date core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'marshal default value as color' '
+	echo "\033[31m" >expect &&
+	git config --default red --color core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'does not allow --default with --replace-all' '
+	test_must_fail git config --default quux --replace-all a b >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --add' '
+	test_must_fail git config --default quux --add a b >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --unset' '
+	test_must_fail git config --default quux --unset a >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --unset-all' '
+	test_must_fail git config --default quux --unset-all a >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --rename-section' '
+	test_must_fail git config --default quux --rename-section a >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --remove-section' '
+	test_must_fail git config --default quux --remove-section a >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --list' '
+	test_must_fail git config --default quux --list >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --edit' '
+	test_must_fail git config --default quux --edit >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --get-color' '
+	test_must_fail git config --default quux --get-color >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_expect_success 'does not allow --default with --get-colorbool' '
+	test_must_fail git config --default quux --get-colorbool >output 2>&1 &&
+	test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_done
-- 
2.15.1.354.g95ec6b1b3