diff options
-rw-r--r-- | Documentation/git-config.txt | 10 | ||||
-rw-r--r-- | builtin/config.c | 40 | ||||
-rw-r--r-- | config.c | 10 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rwxr-xr-x | t/t1300-config.sh | 30 | ||||
-rwxr-xr-x | t/t1310-config-default.sh | 36 |
6 files changed, 127 insertions, 0 deletions
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index b759009c75..18ddc78f42 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -177,6 +177,10 @@ Valid `<type>`'s include: ~/` from the command line to let your shell do the expansion.) - 'expiry-date': canonicalize by converting from a fixed or relative date-string to a timestamp. This specifier has no effect when setting the value. +- 'color': When getting a value, canonicalize by converting to an ANSI color + escape sequence. When setting a value, a sanity-check is performed to ensure + that the given value is canonicalize-able as an ANSI color, but it is written + as-is. + --bool:: @@ -228,6 +232,8 @@ Valid `<type>`'s include: output it as the ANSI color escape sequence to the standard output. The optional `default` parameter is used instead, if there is no color configured for `name`. ++ +`--type=color [--default=<default>]` is preferred over `--get-color`. -e:: --edit:: @@ -240,6 +246,10 @@ Valid `<type>`'s include: using `--file`, `--global`, etc) and `on` when searching all config files. +--default <value>:: + When using `--get`, and the requested variable is not found, behave as if + <value> were the value assigned to the that variable. + CONFIGURATION ------------- `pager.config` is only respected when listing configuration, i.e., when diff --git a/builtin/config.c b/builtin/config.c index 24d735e16a..69e7270356 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, type; +static char *default_value; static int end_null; static int respect_includes_opt = -1; static struct config_options config_options; @@ -60,6 +61,7 @@ static int show_origin; #define TYPE_BOOL_OR_INT 3 #define TYPE_PATH 4 #define TYPE_EXPIRY_DATE 5 +#define TYPE_COLOR 6 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \ { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \ @@ -93,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg, new_type = TYPE_PATH; else if (!strcmp(arg, "expiry-date")) new_type = TYPE_EXPIRY_DATE; + else if (!strcmp(arg, "color")) + new_type = TYPE_COLOR; else die(_("unrecognized --type argument, %s"), arg); } @@ -149,6 +153,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_("with --get, use default value when missing entry")), OPT_END(), }; @@ -228,6 +233,11 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value if (git_config_expiry_date(&t, key_, value_) < 0) return -1; strbuf_addf(buf, "%"PRItime, t); + } else if (type == TYPE_COLOR) { + char v[COLOR_MAXLEN]; + if (git_config_color(v, key_, value_) < 0) + return -1; + strbuf_addstr(buf, v); } else if (value_) { strbuf_addstr(buf, value_); } else { @@ -313,6 +323,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++]; + strbuf_init(item, 0); + if (format_config(item, key_, default_value) < 0) + die(_("failed to format default config value: %s"), + default_value); + } + ret = !values.nr; for (i = 0; i < values.nr; i++) { @@ -363,6 +383,20 @@ static char *normalize_value(const char *key, const char *value) else return xstrdup(v ? "true" : "false"); } + if (type == TYPE_COLOR) { + char v[COLOR_MAXLEN]; + if (git_config_color(v, key, value)) + die("cannot parse color '%s'", value); + + /* + * The contents of `v` now contain an ANSI escape + * sequence, not suitable for including within a + * configuration file. Treat the above as a + * "sanity-check", and return the given value, which we + * know is representable as valid color code. + */ + return xstrdup(value); + } die("BUG: cannot normalize type %d", type); } @@ -651,6 +685,12 @@ 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)) { + error("--default is only applicable to --get"); + usage_with_options(builtin_config_usage, + builtin_config_options); + } + if (actions & PAGING_ACTIONS) setup_auto_pager("config", 1); @@ -16,6 +16,7 @@ #include "string-list.h" #include "utf8.h" #include "dir.h" +#include "color.h" struct config_source { struct config_source *prev; @@ -1067,6 +1068,15 @@ int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char * return 0; } +int git_config_color(char *dest, const char *var, const char *value) +{ + if (!value) + return config_error_nonbool(var); + if (color_parse(value, dest) < 0) + return -1; + return 0; +} + static int git_default_core_config(const char *var, const char *value) { /* This needs a better name */ @@ -84,6 +84,7 @@ extern int git_config_bool(const char *, const char *); extern int git_config_string(const char **, const char *, const char *); extern int git_config_pathname(const char **, const char *, const char *); extern int git_config_expiry_date(timestamp_t *, const char *, const char *); +extern int git_config_color(char *, const char *, const char *); extern int git_config_set_in_file_gently(const char *, const char *, const char *); extern void git_config_set_in_file(const char *, const char *, const char *); extern int git_config_set_gently(const char *, const char *); diff --git a/t/t1300-config.sh b/t/t1300-config.sh index e7e6d07b3a..03c223708e 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -933,6 +933,36 @@ test_expect_success 'get --expiry-date' ' test_must_fail git config --expiry-date date.invalid1 ' +test_expect_success 'get --type=color' ' + rm .git/config && + git config foo.color "red" && + git config --get --type=color foo.color >actual.raw && + test_decode_color <actual.raw >actual && + echo "<RED>" >expect && + test_cmp expect actual +' + +cat >expect << EOF +[foo] + color = red +EOF + +test_expect_success 'set --type=color' ' + rm .git/config && + git config --type=color foo.color "red" && + test_cmp expect .git/config +' + +test_expect_success 'get --type=color barfs on non-color' ' + echo "[foo]bar=not-a-color" >.git/config && + test_must_fail git config --get --type=color foo.bar +' + +test_expect_success 'set --type=color barfs on non-color' ' + test_must_fail git config --type=color foo.color "not-a-color" 2>error && + test_i18ngrep "cannot parse color" error +' + cat > expect << EOF [quote] leading = " test" diff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh new file mode 100755 index 0000000000..6049d91708 --- /dev/null +++ b/t/t1310-config-default.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +test_description='Test git config in different settings (with --default)' + +. ./test-lib.sh + +test_expect_success 'uses --default when entry missing' ' + echo quux >expect && + git config -f config --default=quux core.foo >actual && + test_cmp expect actual +' + +test_expect_success 'does not use --default when entry present' ' + echo bar >expect && + git -c core.foo=bar config --default=baz core.foo >actual && + test_cmp expect actual +' + +test_expect_success 'canonicalizes --default with appropriate type' ' + echo true >expect && + git config -f config --default=yes --bool core.foo >actual && + test_cmp expect actual +' + +test_expect_success 'dies when --default cannot be parsed' ' + test_must_fail git config -f config --type=expiry-date --default=x --get \ + not.a.section 2>error && + test_i18ngrep "failed to format default config value" error +' + +test_expect_success 'does not allow --default without --get' ' + test_must_fail git config --default=quux --unset a.section >output 2>&1 && + test_i18ngrep "\-\-default is only applicable to" output +' + +test_done |