diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-02-15 15:48:44 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-02-21 09:09:40 -0800 |
commit | 93c8d674f29faa3a86157e0bf7a49915b9e5bc2e (patch) | |
tree | a9b7f4c3e728b9e23a8f955e8f14c93b0bcb4efe | |
parent | c3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0 (diff) | |
download | git-93c8d674f29faa3a86157e0bf7a49915b9e5bc2e.tar.gz |
config: preserve <subsection> case for one-shot config on the command line
The "git -c <var>=<val> cmd" mechanism is to pretend that a
configuration variable <var> is set to <val> while the cmd is
running. The code to do so however downcased <var> in its entirety,
which is wrong for a three-level <section>.<subsection>.<variable>.
The <subsection> part needs to stay as-is.
Reported-by: Lars Schneider <larsxschneider@gmail.com>
Diagnosed-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | config.c | 30 | ||||
-rwxr-xr-x | t/t1300-repo-config.sh | 46 |
2 files changed, 75 insertions, 1 deletions
@@ -199,6 +199,34 @@ void git_config_push_parameter(const char *text) strbuf_release(&env); } +/* + * downcase the <section> and <variable> in <section>.<variable> or + * <section>.<subsection>.<variable> and do so in place. <subsection> + * is left intact. + */ +static void canonicalize_config_variable_name(char *varname) +{ + char *cp, *last_dot; + + /* downcase the first segment */ + for (cp = varname; *cp; cp++) { + if (*cp == '.') + break; + *cp = tolower(*cp); + } + if (!*cp) + return; + + /* find the last dot (we start from the first dot we just found) */ + for (last_dot = cp; *cp; cp++) + if (*cp == '.') + last_dot = cp; + + /* downcase the last segment */ + for (cp = last_dot; *cp; cp++) + *cp = tolower(*cp); +} + int git_config_parse_parameter(const char *text, config_fn_t fn, void *data) { @@ -221,7 +249,7 @@ int git_config_parse_parameter(const char *text, strbuf_list_free(pair); return error("bogus config parameter: %s", text); } - strbuf_tolower(pair[0]); + canonicalize_config_variable_name(pair[0]->buf); if (fn(pair[0]->buf, value, data) < 0) { strbuf_list_free(pair); return -1; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 923bfc5a26..7a16f66a9d 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -1097,6 +1097,52 @@ test_expect_success 'multiple git -c appends config' ' test_cmp expect actual ' +test_expect_success 'last one wins: two level vars' ' + + # sec.var and sec.VAR are the same variable, as the first + # and the last level of a configuration variable name is + # case insensitive. + + echo VAL >expect && + + git -c sec.var=val -c sec.VAR=VAL config --get sec.var >actual && + test_cmp expect actual && + git -c SEC.var=val -c sec.var=VAL config --get sec.var >actual && + test_cmp expect actual && + + git -c sec.var=val -c sec.VAR=VAL config --get SEC.var >actual && + test_cmp expect actual && + git -c SEC.var=val -c sec.var=VAL config --get sec.VAR >actual && + test_cmp expect actual +' + +test_expect_success 'last one wins: three level vars' ' + + # v.a.r and v.A.r are not the same variable, as the middle + # level of a three-level configuration variable name is + # case sensitive. + + echo val >expect && + git -c v.a.r=val -c v.A.r=VAL config --get v.a.r >actual && + test_cmp expect actual && + git -c v.a.r=val -c v.A.r=VAL config --get V.a.R >actual && + test_cmp expect actual && + + # v.a.r and V.a.R are the same variable, as the first + # and the last level of a configuration variable name is + # case insensitive. + + echo VAL >expect && + git -c v.a.r=val -c v.a.R=VAL config --get v.a.r >actual && + test_cmp expect actual && + git -c v.a.r=val -c V.a.r=VAL config --get v.a.r >actual && + test_cmp expect actual && + git -c v.a.r=val -c v.a.R=VAL config --get V.a.R >actual && + test_cmp expect actual && + git -c v.a.r=val -c V.a.r=VAL config --get V.a.R >actual && + test_cmp expect actual +' + test_expect_success 'git -c is not confused by empty environment' ' GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list ' |