From: Junio C Hamano Date: Wed, 21 Nov 2012 21:16:44 +0000 (-0800) Subject: Merge branch 'jk/config-ignore-duplicates' X-Git-Tag: v1.8.1-rc0~40 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2739889c98e8d1c1a40263f7f7c0866879c31edf?ds=inline;hp=-c Merge branch 'jk/config-ignore-duplicates' Drop duplicate detection from "git-config --get"; this lets it better match the internal config callbacks, which clears up some corner cases with includes. * jk/config-ignore-duplicates: builtin/config.c: Fix a sparse warning git-config: use git_config_with_options git-config: do not complain about duplicate entries git-config: collect values instead of immediately printing git-config: fix regexp memory leaks on error conditions git-config: remove memory leak of key regexp t1300: test "git config --get-all" more thoroughly t1300: remove redundant test t1300: style updates --- 2739889c98e8d1c1a40263f7f7c0866879c31edf diff --combined builtin/config.c index 505bbc7ddd,e796af4db6..33c9bf9d84 --- a/builtin/config.c +++ b/builtin/config.c @@@ -15,7 -15,6 +15,6 @@@ static int show_keys static int use_key_regexp; static int do_all; static int do_not_match; - static int seen; static char delim = '='; static char key_delim = ' '; static char term = '\n'; @@@ -95,12 -94,19 +94,19 @@@ static int show_all_config(const char * return 0; } - static int show_config(const char *key_, const char *value_, void *cb) + struct strbuf_list { + struct strbuf *items; + int nr; + int alloc; + }; + + static int collect_config(const char *key_, const char *value_, void *cb) { + struct strbuf_list *values = cb; + struct strbuf *buf; char value[256]; const char *vptr = value; int must_free_vptr = 0; - int dup_error = 0; int must_print_delim = 0; if (!use_key_regexp && strcmp(key_, key)) @@@ -111,12 -117,14 +117,14 @@@ (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0))) return 0; + ALLOC_GROW(values->items, values->nr + 1, values->alloc); + buf = &values->items[values->nr++]; + strbuf_init(buf, 0); + if (show_keys) { - printf("%s", key_); + strbuf_addstr(buf, key_); must_print_delim = 1; } - if (seen && !do_all) - dup_error = 1; if (types == TYPE_INT) sprintf(value, "%d", git_config_int(key_, value_?value_:"")); else if (types == TYPE_BOOL) @@@ -129,8 -137,7 +137,8 @@@ else sprintf(value, "%d", v); } else if (types == TYPE_PATH) { - git_config_pathname(&vptr, key_, value_); + if (git_config_pathname(&vptr, key_, value_) < 0) + return -1; must_free_vptr = 1; } else if (value_) { vptr = value_; @@@ -139,16 -146,12 +147,12 @@@ vptr = ""; must_print_delim = 0; } - seen++; - if (dup_error) { - error("More than one value for the key %s: %s", - key_, vptr); - } - else { - if (must_print_delim) - printf("%c", key_delim); - printf("%s%c", vptr, term); - } + + if (must_print_delim) + strbuf_addch(buf, key_delim); + strbuf_addstr(buf, vptr); + strbuf_addch(buf, term); + if (must_free_vptr) /* If vptr must be freed, it's a pointer to a * dynamically allocated buffer, it's safe to cast to @@@ -162,19 -165,8 +166,8 @@@ static int get_value(const char *key_, const char *regex_) { int ret = CONFIG_GENERIC_ERROR; - char *global = NULL, *xdg = NULL, *repo_config = NULL; - const char *system_wide = NULL, *local; - struct config_include_data inc = CONFIG_INCLUDE_INIT; - config_fn_t fn; - void *data; - - local = given_config_file; - if (!local) { - local = repo_config = git_pathdup("config"); - if (git_config_system()) - system_wide = git_etc_gitconfig(); - home_config_paths(&global, &xdg, "config"); - } + struct strbuf_list values = {NULL}; + int i; if (use_key_regexp) { char *tl; @@@ -196,7 -188,8 +189,8 @@@ key_regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(key_regexp, key, REG_EXTENDED)) { fprintf(stderr, "Invalid key pattern: %s\n", key_); - free(key); + free(key_regexp); + key_regexp = NULL; ret = CONFIG_INVALID_PATTERN; goto free_strings; } @@@ -216,53 -209,37 +210,37 @@@ regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(regexp, regex_, REG_EXTENDED)) { fprintf(stderr, "Invalid pattern: %s\n", regex_); + free(regexp); + regexp = NULL; ret = CONFIG_INVALID_PATTERN; goto free_strings; } } - fn = show_config; - data = NULL; - if (respect_includes) { - inc.fn = fn; - inc.data = data; - fn = git_config_include; - data = &inc; - } + git_config_with_options(collect_config, &values, + given_config_file, respect_includes); + + ret = !values.nr; - if (do_all && system_wide) - git_config_from_file(fn, system_wide, data); - if (do_all && xdg) - git_config_from_file(fn, xdg, data); - if (do_all && global) - git_config_from_file(fn, global, data); - if (do_all) - git_config_from_file(fn, local, data); - git_config_from_parameters(fn, data); - if (!do_all && !seen) - git_config_from_file(fn, local, data); - if (!do_all && !seen && global) - git_config_from_file(fn, global, data); - if (!do_all && !seen && xdg) - git_config_from_file(fn, xdg, data); - if (!do_all && !seen && system_wide) - git_config_from_file(fn, system_wide, data); + for (i = 0; i < values.nr; i++) { + struct strbuf *buf = values.items + i; + if (do_all || i == values.nr - 1) + fwrite(buf->buf, 1, buf->len, stdout); + strbuf_release(buf); + } + free(values.items); + free_strings: free(key); + if (key_regexp) { + regfree(key_regexp); + free(key_regexp); + } if (regexp) { regfree(regexp); free(regexp); } - if (do_all) - ret = !seen; - else - ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1; - - free_strings: - free(repo_config); - free(global); - free(xdg); return ret; } diff --combined config.c index fff8a43bc0,2fbe634b17..fb3f8681ee --- a/config.c +++ b/config.c @@@ -10,6 -10,8 +10,6 @@@ #include "strbuf.h" #include "quote.h" -#define MAXNAME (256) - typedef struct config_file { struct config_file *prev; FILE *f; @@@ -17,7 -19,7 +17,7 @@@ int linenr; int eof; struct strbuf value; - char var[MAXNAME]; + struct strbuf var; } config_file; static config_file *cf; @@@ -258,7 -260,7 +258,7 @@@ static inline int iskeychar(int c return isalnum(c) || c == '-'; } -static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) +static int get_value(config_fn_t fn, void *data, struct strbuf *name) { int c; char *value; @@@ -270,9 -272,11 +270,9 @@@ break; if (!iskeychar(c)) break; - name[len++] = tolower(c); - if (len >= MAXNAME) - return -1; + strbuf_addch(name, tolower(c)); } - name[len] = 0; + while (c == ' ' || c == '\t') c = get_next_char(); @@@ -284,10 -288,10 +284,10 @@@ if (!value) return -1; } - return fn(name, value, data); + return fn(name->buf, value, data); } -static int get_extended_base_var(char *name, int baselen, int c) +static int get_extended_base_var(struct strbuf *name, int c) { do { if (c == '\n') @@@ -298,7 -302,7 +298,7 @@@ /* We require the format to be '[base "extension"]' */ if (c != '"') return -1; - name[baselen++] = '.'; + strbuf_addch(name, '.'); for (;;) { int c = get_next_char(); @@@ -311,31 -315,37 +311,31 @@@ if (c == '\n') goto error_incomplete_line; } - name[baselen++] = c; - if (baselen > MAXNAME / 2) - return -1; + strbuf_addch(name, c); } /* Final ']' */ if (get_next_char() != ']') return -1; - return baselen; + return 0; error_incomplete_line: cf->linenr--; return -1; } -static int get_base_var(char *name) +static int get_base_var(struct strbuf *name) { - int baselen = 0; - for (;;) { int c = get_next_char(); if (cf->eof) return -1; if (c == ']') - return baselen; + return 0; if (isspace(c)) - return get_extended_base_var(name, baselen, c); + return get_extended_base_var(name, c); if (!iskeychar(c) && c != '.') return -1; - if (baselen > MAXNAME / 2) - return -1; - name[baselen++] = tolower(c); + strbuf_addch(name, tolower(c)); } } @@@ -343,7 -353,7 +343,7 @@@ static int git_parse_file(config_fn_t f { int comment = 0; int baselen = 0; - char *var = cf->var; + struct strbuf *var = &cf->var; /* U+FEFF Byte Order Mark in UTF8 */ static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf"; @@@ -379,24 -389,17 +379,24 @@@ continue; } if (c == '[') { - baselen = get_base_var(var); - if (baselen <= 0) + /* Reset prior to determining a new stem */ + strbuf_reset(var); + if (get_base_var(var) < 0 || var->len < 1) break; - var[baselen++] = '.'; - var[baselen] = 0; + strbuf_addch(var, '.'); + baselen = var->len; continue; } if (!isalpha(c)) break; - var[baselen] = tolower(c); - if (get_value(fn, data, var, baselen+1) < 0) + /* + * Truncate the var name back to the section header + * stem prior to grabbing the suffix part of the name + * and the value. + */ + strbuf_setlen(var, baselen); + strbuf_addch(var, tolower(c)); + if (get_value(fn, data, var) < 0) break; } die("bad config file line %d in %s", cf->linenr, cf->name); @@@ -896,14 -899,12 +896,14 @@@ int git_config_from_file(config_fn_t fn top.linenr = 1; top.eof = 0; strbuf_init(&top.value, 1024); + strbuf_init(&top.var, 1024); cf = ⊤ ret = git_parse_file(fn, data); /* pop config-file parsing state stack */ strbuf_release(&top.value); + strbuf_release(&top.var); cf = top.prev; fclose(f); @@@ -1279,6 -1280,7 +1279,7 @@@ int git_config_parse_key(const char *ke out_free_ret_1: free(*store_key); + *store_key = NULL; return -CONFIG_INVALID_KEY; } diff --combined t/t1300-repo-config.sh index 7c4c372e37,97a25f1484..3c96fda548 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@@ -55,11 -55,13 +55,13 @@@ test_expect_success 'uppercase section test_cmp expect .git/config ' - test_expect_success 'replace with non-match' \ - 'git config core.penguin kingpin !blue' + test_expect_success 'replace with non-match' ' + git config core.penguin kingpin !blue + ' - test_expect_success 'replace with non-match (actually matching)' \ - 'git config core.penguin "very blue" !kingpin' + test_expect_success 'replace with non-match (actually matching)' ' + git config core.penguin "very blue" !kingpin + ' cat > expect << EOF [core] @@@ -108,8 -110,9 +110,9 @@@ baz = multiple lines EOF - test_expect_success 'unset with cont. lines' \ - 'git config --unset beta.baz' + test_expect_success 'unset with cont. lines' ' + git config --unset beta.baz + ' cat > expect <<\EOF [alpha] @@@ -133,8 -136,9 +136,9 @@@ EO cp .git/config .git/config2 - test_expect_success 'multiple unset' \ - 'git config --unset-all beta.haha' + test_expect_success 'multiple unset' ' + git config --unset-all beta.haha + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -145,7 -149,9 +149,9 @@@ noIndent= sillyValue ; 'nother silly co [nextSection] noNewline = ouch EOF - test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config' + test_expect_success 'multiple unset is correct' ' + test_cmp expect .git/config + ' cp .git/config2 .git/config @@@ -156,8 -162,9 +162,9 @@@ test_expect_success '--replace-all miss rm .git/config2 - test_expect_success '--replace-all' \ - 'git config --replace-all beta.haha gamma' + test_expect_success '--replace-all' ' + git config --replace-all beta.haha gamma + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -169,7 -176,9 +176,9 @@@ noIndent= sillyValue ; 'nother silly co [nextSection] noNewline = ouch EOF - test_expect_success 'all replaced' 'test_cmp expect .git/config' + test_expect_success 'all replaced' ' + test_cmp expect .git/config + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -200,7 -209,11 +209,11 @@@ test_expect_success 'really really mea test_cmp expect .git/config ' - test_expect_success 'get value' 'test alpha = $(git config beta.haha)' + test_expect_success 'get value' ' + echo alpha >expect && + git config beta.haha >actual && + test_cmp expect actual + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -231,18 -244,30 +244,30 @@@ test_expect_success 'multivar' test_cmp expect .git/config ' - test_expect_success 'non-match' \ - 'git config --get nextsection.nonewline !for' + test_expect_success 'non-match' ' + git config --get nextsection.nonewline !for + ' - test_expect_success 'non-match value' \ - 'test wow = $(git config --get nextsection.nonewline !for)' + test_expect_success 'non-match value' ' + echo wow >expect && + git config --get nextsection.nonewline !for >actual && + test_cmp expect actual + ' - test_expect_success 'ambiguous get' ' - test_must_fail git config --get nextsection.nonewline + test_expect_success 'multi-valued get returns final one' ' + echo "wow2 for me" >expect && + git config --get nextsection.nonewline >actual && + test_cmp expect actual ' - test_expect_success 'get multivar' \ - 'git config --get-all nextsection.nonewline' + test_expect_success 'multi-valued get-all returns all' ' + cat >expect <<-\EOF && + wow + wow2 for me + EOF + git config --get-all nextsection.nonewline >actual && + test_cmp expect actual + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -259,10 -284,6 +284,6 @@@ test_expect_success 'multivar replace' test_cmp expect .git/config ' - test_expect_success 'ambiguous value' ' - test_must_fail git config nextsection.nonewline - ' - test_expect_success 'ambiguous unset' ' test_must_fail git config --unset nextsection.nonewline ' @@@ -290,8 -311,9 +311,9 @@@ test_expect_success 'invalid key' 'test test_expect_success 'correct key' 'git config 123456.a123 987' - test_expect_success 'hierarchical section' \ - 'git config Version.1.2.3eX.Alpha beta' + test_expect_success 'hierarchical section' ' + git config Version.1.2.3eX.Alpha beta + ' cat > expect << EOF [beta] ; silly comment # another comment @@@ -307,7 -329,9 +329,9 @@@ noIndent= sillyValue ; 'nother silly co Alpha = beta EOF - test_expect_success 'hierarchical section value' 'test_cmp expect .git/config' + test_expect_success 'hierarchical section value' ' + test_cmp expect .git/config + ' cat > expect << EOF beta.noindent=sillyValue @@@ -316,9 -340,10 +340,10 @@@ nextsection.nonewline=wow2 for m version.1.2.3eX.alpha=beta EOF - test_expect_success 'working --list' \ - 'git config --list > output && cmp output expect' - + test_expect_success 'working --list' ' + git config --list > output && + test_cmp expect output + ' cat > expect << EOF EOF @@@ -332,8 -357,10 +357,10 @@@ beta.noindent sillyValu nextsection.nonewline wow2 for me EOF - test_expect_success '--get-regexp' \ - 'git config --get-regexp in > output && cmp output expect' + test_expect_success '--get-regexp' ' + git config --get-regexp in >output && + test_cmp expect output + ' cat > expect << EOF wow2 for me @@@ -353,41 -380,48 +380,48 @@@ cat > .git/config << EO variable = EOF - test_expect_success 'get variable with no value' \ - 'git config --get novalue.variable ^$' + test_expect_success 'get variable with no value' ' + git config --get novalue.variable ^$ + ' - test_expect_success 'get variable with empty value' \ - 'git config --get emptyvalue.variable ^$' + test_expect_success 'get variable with empty value' ' + git config --get emptyvalue.variable ^$ + ' echo novalue.variable > expect - test_expect_success 'get-regexp variable with no value' \ - 'git config --get-regexp novalue > output && - cmp output expect' + test_expect_success 'get-regexp variable with no value' ' + git config --get-regexp novalue > output && + test_cmp expect output + ' echo 'novalue.variable true' > expect - test_expect_success 'get-regexp --bool variable with no value' \ - 'git config --bool --get-regexp novalue > output && - cmp output expect' + test_expect_success 'get-regexp --bool variable with no value' ' + git config --bool --get-regexp novalue > output && + test_cmp expect output + ' echo 'emptyvalue.variable ' > expect - test_expect_success 'get-regexp variable with empty value' \ - 'git config --get-regexp emptyvalue > output && - cmp output expect' + test_expect_success 'get-regexp variable with empty value' ' + git config --get-regexp emptyvalue > output && + test_cmp expect output + ' echo true > expect - test_expect_success 'get bool variable with no value' \ - 'git config --bool novalue.variable > output && - cmp output expect' + test_expect_success 'get bool variable with no value' ' + git config --bool novalue.variable > output && + test_cmp expect output + ' echo false > expect - test_expect_success 'get bool variable with empty value' \ - 'git config --bool emptyvalue.variable > output && - cmp output expect' + test_expect_success 'get bool variable with empty value' ' + git config --bool emptyvalue.variable > output && + test_cmp expect output + ' test_expect_success 'no arguments, but no crash' ' test_must_fail git config >output 2>&1 && @@@ -427,8 -461,9 +461,9 @@@ test_expect_success 'new variable inser test_cmp expect .git/config ' - test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \ - 'test_must_fail git config --file non-existing-config -l' + test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' ' + test_must_fail git config --file non-existing-config -l + ' cat > other-config << EOF [ein] @@@ -444,8 -479,10 +479,10 @@@ test_expect_success 'alternative GIT_CO test_cmp expect output ' - test_expect_success 'alternative GIT_CONFIG (--file)' \ - 'git config --file other-config -l > output && cmp output expect' + test_expect_success 'alternative GIT_CONFIG (--file)' ' + git config --file other-config -l > output && + test_cmp expect output + ' test_expect_success 'refer config from subdirectory' ' mkdir x && @@@ -489,8 -526,9 +526,9 @@@ cat > .git/config << EO weird EOF - test_expect_success "rename section" \ - "git config --rename-section branch.eins branch.zwei" + test_expect_success 'rename section' ' + git config --rename-section branch.eins branch.zwei + ' cat > expect << EOF # Hallo @@@ -503,17 -541,22 +541,22 @@@ weird EOF - test_expect_success "rename succeeded" "test_cmp expect .git/config" + test_expect_success 'rename succeeded' ' + test_cmp expect .git/config + ' - test_expect_success "rename non-existing section" ' + test_expect_success 'rename non-existing section' ' test_must_fail git config --rename-section \ branch."world domination" branch.drei ' - test_expect_success "rename succeeded" "test_cmp expect .git/config" + test_expect_success 'rename succeeded' ' + test_cmp expect .git/config + ' - test_expect_success "rename another section" \ - 'git config --rename-section branch."1 234 blabl/a" branch.drei' + test_expect_success 'rename another section' ' + git config --rename-section branch."1 234 blabl/a" branch.drei + ' cat > expect << EOF # Hallo @@@ -526,14 -569,17 +569,17 @@@ weird EOF - test_expect_success "rename succeeded" "test_cmp expect .git/config" + test_expect_success 'rename succeeded' ' + test_cmp expect .git/config + ' cat >> .git/config << EOF [branch "vier"] z = 1 EOF - test_expect_success "rename a section with a var on the same line" \ - 'git config --rename-section branch.vier branch.zwei' + test_expect_success 'rename a section with a var on the same line' ' + git config --rename-section branch.vier branch.zwei + ' cat > expect << EOF # Hallo @@@ -548,7 -594,9 +594,9 @@@ weir z = 1 EOF - test_expect_success "rename succeeded" "test_cmp expect .git/config" + test_expect_success 'rename succeeded' ' + test_cmp expect .git/config + ' test_expect_success 'renaming empty section name is rejected' ' test_must_fail git config --rename-section branch.zwei "" @@@ -562,7 -610,9 +610,9 @@@ cat >> .git/config << EO [branch "zwei"] a = 1 [branch "vier"] EOF - test_expect_success "remove section" "git config --remove-section branch.zwei" + test_expect_success 'remove section' ' + git config --remove-section branch.zwei + ' cat > expect << EOF # Hallo @@@ -571,8 -621,9 +621,9 @@@ weird EOF - test_expect_success "section was removed properly" \ - "test_cmp expect .git/config" + test_expect_success 'section was removed properly' ' + test_cmp expect .git/config + ' cat > expect << EOF [gitcvs] @@@ -583,7 -634,6 +634,6 @@@ EOF test_expect_success 'section ending' ' - rm -f .git/config && git config gitcvs.enabled true && git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && @@@ -593,30 -643,25 +643,25 @@@ ' test_expect_success numbers ' - git config kilo.gram 1k && git config mega.ton 1m && - k=$(git config --int --get kilo.gram) && - test z1024 = "z$k" && - m=$(git config --int --get mega.ton) && - test z1048576 = "z$m" + echo 1024 >expect && + echo 1048576 >>expect && + git config --int --get kilo.gram >actual && + git config --int --get mega.ton >>actual && + test_cmp expect actual ' - cat > expect <actual - then - echo config should have failed - false - fi && - cmp actual expect + echo 1auto >expect && + git config aninvalid.unit >actual && + test_cmp expect actual && + cat > expect <<-\EOF + fatal: bad config value for '\''aninvalid.unit'\'' in .git/config + EOF + test_must_fail git config --int --get aninvalid.unit 2>actual && + test_cmp actual expect ' cat > expect << EOF @@@ -646,7 -691,7 +691,7 @@@ test_expect_success bool git config --bool --get bool.true$i >>result git config --bool --get bool.false$i >>result done && - cmp expect result' + test_cmp expect result' test_expect_success 'invalid bool (--get)' ' @@@ -680,7 -725,7 +725,7 @@@ test_expect_success 'set --bool' git config --bool bool.false2 "" && git config --bool bool.false3 nO && git config --bool bool.false4 FALSE && - cmp expect .git/config' + test_cmp expect .git/config' cat > expect <<\EOF [int] @@@ -695,39 -740,37 +740,37 @@@ test_expect_success 'set --int' git config --int int.val1 01 && git config --int int.val2 -1 && git config --int int.val3 5m && - cmp expect .git/config' + test_cmp expect .git/config + ' - cat >expect <<\EOF - [bool] - true1 = true + test_expect_success 'get --bool-or-int' ' + cat >.git/config <<-\EOF && + [bool] + true1 true2 = true - false1 = false - false2 = false - [int] + false = false + [int] int1 = 0 int2 = 1 int3 = -1 - EOF - - test_expect_success 'get --bool-or-int' ' - rm -f .git/config && - ( - echo "[bool]" - echo true1 - echo true2 = true - echo false = false - echo "[int]" - echo int1 = 0 - echo int2 = 1 - echo int3 = -1 - ) >>.git/config && - test $(git config --bool-or-int bool.true1) = true && - test $(git config --bool-or-int bool.true2) = true && - test $(git config --bool-or-int bool.false) = false && - test $(git config --bool-or-int int.int1) = 0 && - test $(git config --bool-or-int int.int2) = 1 && - test $(git config --bool-or-int int.int3) = -1 - + EOF + cat >expect <<-\EOF && + true + true + false + 0 + 1 + -1 + EOF + { + git config --bool-or-int bool.true1 && + git config --bool-or-int bool.true2 && + git config --bool-or-int bool.false && + git config --bool-or-int int.int1 && + git config --bool-or-int int.int2 && + git config --bool-or-int int.int3 + } >actual && + test_cmp expect actual ' cat >expect <<\EOF @@@ -803,11 -846,6 +846,11 @@@ test_expect_success NOT_MINGW 'get --pa test_cmp expect result ' +test_expect_success 'get --path barfs on boolean variable' ' + echo "[path]bool" >.git/config && + test_must_fail git config --get --path path.bool +' + cat > expect << EOF [quote] leading = " test" @@@ -849,7 -887,7 +892,7 @@@ EO test_expect_success 'value continued on next line' ' git config --list > result && - cmp result expect + test_cmp result expect ' cat > .git/config <<\EOF @@@ -885,11 -923,12 +928,12 @@@ test_expect_success '--null --get-regex test_expect_success 'inner whitespace kept verbatim' ' git config section.val "foo bar" && - test "z$(git config section.val)" = "zfoo bar" + echo "foo bar" >expect && + git config section.val >actual && + test_cmp expect actual ' test_expect_success SYMLINKS 'symlinked configuration' ' - ln -s notyet myconfig && GIT_CONFIG=myconfig git config test.frotz nitfol && test -h myconfig && @@@ -898,9 -937,15 +942,15 @@@ GIT_CONFIG=myconfig git config test.xyzzy rezrov && test -h myconfig && test -f notyet && - test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol && - test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov - + cat >expect <<-\EOF && + nitfol + rezrov + EOF + { + GIT_CONFIG=notyet git config test.frotz && + GIT_CONFIG=notyet git config test.xyzzy + } >actual && + test_cmp expect actual ' test_expect_success 'nonexistent configuration' ' @@@ -932,12 -977,20 +982,20 @@@ test_expect_success 'check split_cmdlin git commit -m 'initial commit' && git config branch.master.mergeoptions 'echo \"' && test_must_fail git merge master - " + " test_expect_success 'git -c "key=value" support' ' - test "z$(git -c core.name=value config core.name)" = zvalue && - test "z$(git -c foo.CamelCase=value config foo.camelcase)" = zvalue && - test "z$(git -c foo.flag config --bool foo.flag)" = ztrue && + cat >expect <<-\EOF && + value + value + true + EOF + { + git -c core.name=value config core.name && + git -c foo.CamelCase=value config foo.camelcase && + git -c foo.flag config --bool foo.flag + } >actual && + test_cmp expect actual && test_must_fail git -c name=value config core.name '