Imported Upstream version 2.16.4
[platform/upstream/git.git] / t / t1300-repo-config.sh
index 3c96fda..cbeb9be 100755 (executable)
@@ -353,6 +353,18 @@ test_expect_success '--list without repo produces empty output' '
 '
 
 cat > expect << EOF
+beta.noindent
+nextsection.nonewline
+123456.a123
+version.1.2.3eX.alpha
+EOF
+
+test_expect_success '--name-only --list' '
+       git config --name-only --list >output &&
+       test_cmp expect output
+'
+
+cat > expect << EOF
 beta.noindent sillyValue
 nextsection.nonewline wow2 for me
 EOF
@@ -363,6 +375,16 @@ test_expect_success '--get-regexp' '
 '
 
 cat > expect << EOF
+beta.noindent
+nextsection.nonewline
+EOF
+
+test_expect_success '--name-only --get-regexp' '
+       git config --name-only --get-regexp in >output &&
+       test_cmp expect output
+'
+
+cat > expect << EOF
 wow2 for me
 wow4 for you
 EOF
@@ -461,7 +483,7 @@ test_expect_success 'new variable inserts into proper section' '
        test_cmp expect .git/config
 '
 
-test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' '
+test_expect_success 'alternative --file (non-existing file should fail)' '
        test_must_fail git config --file non-existing-config -l
 '
 
@@ -475,15 +497,28 @@ ein.bahn=strasse
 EOF
 
 test_expect_success 'alternative GIT_CONFIG' '
-       GIT_CONFIG=other-config git config -l >output &&
+       GIT_CONFIG=other-config git config --list >output &&
        test_cmp expect output
 '
 
 test_expect_success 'alternative GIT_CONFIG (--file)' '
-       git config --file other-config -l > output &&
+       git config --file other-config --list >output &&
        test_cmp expect output
 '
 
+test_expect_success 'alternative GIT_CONFIG (--file=-)' '
+       git config --file - --list <other-config >output &&
+       test_cmp expect output
+'
+
+test_expect_success 'setting a value in stdin is an error' '
+       test_must_fail git config --file - some.value foo
+'
+
+test_expect_success 'editing stdin is an error' '
+       test_must_fail git config --file - --edit
+'
+
 test_expect_success 'refer config from subdirectory' '
        mkdir x &&
        (
@@ -495,10 +530,10 @@ test_expect_success 'refer config from subdirectory' '
 
 '
 
-test_expect_success 'refer config from subdirectory via GIT_CONFIG' '
+test_expect_success 'refer config from subdirectory via --file' '
        (
                cd x &&
-               GIT_CONFIG=../other-config git config --get ein.bahn >actual &&
+               git config --file=../other-config --get ein.bahn >actual &&
                test_cmp expect actual
        )
 '
@@ -510,8 +545,8 @@ cat > expect << EOF
        park = ausweis
 EOF
 
-test_expect_success '--set in alternative GIT_CONFIG' '
-       GIT_CONFIG=other-config git config anwohner.park ausweis &&
+test_expect_success '--set in alternative file' '
+       git config --file=other-config anwohner.park ausweis &&
        test_cmp expect other-config
 '
 
@@ -652,16 +687,31 @@ test_expect_success numbers '
        test_cmp expect actual
 '
 
+test_expect_success '--int is at least 64 bits' '
+       git config giga.watts 121g &&
+       echo 129922760704 >expect &&
+       git config --int --get giga.watts >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'invalid unit' '
        git config aninvalid.unit "1auto" &&
        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
+       test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
+'
+
+test_expect_success 'line number is reported correctly' '
+       printf "[bool]\n\tvar\n" >invalid &&
+       test_must_fail git config -f invalid --path bool.var 2>actual &&
+       test_i18ngrep "line 2" actual
+'
+
+test_expect_success 'invalid stdin config' '
+       echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
+       test_i18ngrep "bad config line 1 in standard input" output
 '
 
 cat > expect << EOF
@@ -804,14 +854,14 @@ cat >expect <<\EOF
        trailingtilde = foo~
 EOF
 
-test_expect_success NOT_MINGW 'set --path' '
+test_expect_success !MINGW 'set --path' '
        rm -f .git/config &&
        git config --path path.home "~/" &&
        git config --path path.normal "/dev/null" &&
        git config --path path.trailingtilde "foo~" &&
        test_cmp expect .git/config'
 
-if test_have_prereq NOT_MINGW && test "${HOME+set}"
+if test_have_prereq !MINGW && test "${HOME+set}"
 then
        test_set_prereq HOMEVAR
 fi
@@ -834,7 +884,7 @@ cat >expect <<\EOF
 foo~
 EOF
 
-test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '
+test_expect_success !MINGW 'get --path copes with unset $HOME' '
        (
                unset HOME;
                test_must_fail git config --get --path path.home \
@@ -842,7 +892,7 @@ test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '
                git config --get --path path.normal >>result &&
                git config --get --path path.trailingtilde >>result
        ) &&
-       grep "[Ff]ailed to expand.*~/" msg &&
+       test_i18ngrep "[Ff]ailed to expand.*~/" msg &&
        test_cmp expect result
 '
 
@@ -851,6 +901,36 @@ test_expect_success 'get --path barfs on boolean variable' '
        test_must_fail git config --get --path path.bool
 '
 
+test_expect_success 'get --expiry-date' '
+       rel="3.weeks.5.days.00:00" &&
+       rel_out="$rel ->" &&
+       cat >.git/config <<-\EOF &&
+       [date]
+       valid1 = "3.weeks.5.days 00:00"
+       valid2 = "Fri Jun 4 15:46:55 2010"
+       valid3 = "2017/11/11 11:11:11PM"
+       valid4 = "2017/11/10 09:08:07 PM"
+       valid5 = "never"
+       invalid1 = "abc"
+       EOF
+       cat >expect <<-EOF &&
+       $(test-date timestamp $rel)
+       1275666415
+       1510441871
+       1510348087
+       0
+       EOF
+       {
+               echo "$rel_out $(git config --expiry-date date.valid1)"
+               git config --expiry-date date.valid2 &&
+               git config --expiry-date date.valid3 &&
+               git config --expiry-date date.valid4 &&
+               git config --expiry-date date.valid5
+       } >actual &&
+       test_cmp expect actual &&
+       test_must_fail git config --expiry-date date.invalid1
+'
+
 cat > expect << EOF
 [quote]
        leading = " test"
@@ -915,13 +995,15 @@ Qsection.sub=section.val4
 Qsection.sub=section.val5Q
 EOF
 test_expect_success '--null --list' '
-       git config --null --list | nul_to_q >result &&
+       git config --null --list >result.raw &&
+       nul_to_q <result.raw >result &&
        echo >>result &&
        test_cmp expect result
 '
 
 test_expect_success '--null --get-regexp' '
-       git config --null --get-regexp "val[0-9]" | nul_to_q >result &&
+       git config --null --get-regexp "val[0-9]" >result.raw &&
+       nul_to_q <result.raw >result &&
        echo >>result &&
        test_cmp expect result
 '
@@ -935,11 +1017,11 @@ test_expect_success 'inner whitespace kept verbatim' '
 
 test_expect_success SYMLINKS 'symlinked configuration' '
        ln -s notyet myconfig &&
-       GIT_CONFIG=myconfig git config test.frotz nitfol &&
+       git config --file=myconfig test.frotz nitfol &&
        test -h myconfig &&
        test -f notyet &&
-       test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol &&
-       GIT_CONFIG=myconfig git config test.xyzzy rezrov &&
+       test "z$(git config --file=notyet test.frotz)" = znitfol &&
+       git config --file=myconfig test.xyzzy rezrov &&
        test -h myconfig &&
        test -f notyet &&
        cat >expect <<-\EOF &&
@@ -947,31 +1029,22 @@ test_expect_success SYMLINKS 'symlinked configuration' '
        rezrov
        EOF
        {
-               GIT_CONFIG=notyet git config test.frotz &&
-               GIT_CONFIG=notyet git config test.xyzzy
+               git config --file=notyet test.frotz &&
+               git config --file=notyet test.xyzzy
        } >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'nonexistent configuration' '
-       (
-               GIT_CONFIG=doesnotexist &&
-               export GIT_CONFIG &&
-               test_must_fail git config --list &&
-               test_must_fail git config test.xyzzy
-       )
+       test_must_fail git config --file=doesnotexist --list &&
+       test_must_fail git config --file=doesnotexist test.xyzzy
 '
 
 test_expect_success SYMLINKS 'symlink to nonexistent configuration' '
        ln -s doesnotexist linktonada &&
        ln -s linktonada linktolinktonada &&
-       (
-               GIT_CONFIG=linktonada &&
-               export GIT_CONFIG &&
-               test_must_fail git config --list &&
-               GIT_CONFIG=linktolinktonada &&
-               test_must_fail git config --list
-       )
+       test_must_fail git config --file=linktonada --list &&
+       test_must_fail git config --file=linktolinktonada --list
 '
 
 test_expect_success 'check split_cmdline return' "
@@ -999,6 +1072,17 @@ test_expect_success 'git -c "key=value" support' '
        test_must_fail git -c name=value config core.name
 '
 
+# We just need a type-specifier here that cares about the
+# distinction internally between a NULL boolean and a real
+# string (because most of git's internal parsers do care).
+# Using "--path" works, but we do not otherwise care about
+# its semantics.
+test_expect_success 'git -c can represent empty string' '
+       echo >expect &&
+       git -c foo.empty= config --path foo.empty >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'key sanity-checking' '
        test_must_fail git config foo=bar &&
        test_must_fail git config foo=.bar &&
@@ -1021,6 +1105,13 @@ test_expect_success 'git -c works with aliases of builtins' '
        test_cmp expect actual
 '
 
+test_expect_success 'aliases can be CamelCased' '
+       test_config alias.CamelCased "rev-parse HEAD" &&
+       git CamelCased >out &&
+       git rev-parse HEAD >expect &&
+       test_cmp expect out
+'
+
 test_expect_success 'git -c does not split values on equals' '
        echo "value with = in it" >expect &&
        git -c core.foo="value with = in it" config core.foo >actual &&
@@ -1039,6 +1130,82 @@ test_expect_success 'git -c complains about empty key and value' '
        test_must_fail git -c "" rev-parse
 '
 
+test_expect_success 'multiple git -c appends config' '
+       test_config alias.x "!git -c x.two=2 config --get-regexp ^x\.*" &&
+       cat >expect <<-\EOF &&
+       x.one 1
+       x.two 2
+       EOF
+       git -c x.one=1 x >actual &&
+       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
+'
+
+for VAR in a .a a. a.0b a."b c". a."b c".0d
+do
+       test_expect_success "git -c $VAR=VAL rejects invalid '$VAR'" '
+               test_must_fail git -c "$VAR=VAL" config -l
+       '
+done
+
+for VAR in a.b a."b c".d
+do
+       test_expect_success "git -c $VAR=VAL works with valid '$VAR'" '
+               echo VAL >expect &&
+               git -c "$VAR=VAL" config --get "$VAR" >actual &&
+               test_cmp expect actual
+       '
+done
+
+test_expect_success 'git -c is not confused by empty environment' '
+       GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
+'
+
 test_expect_success 'git config --edit works' '
        git config -f tmp test.value no &&
        echo test.value=yes >expect &&
@@ -1064,7 +1231,7 @@ test_expect_success 'barf on syntax error' '
        key garbage
        EOF
        test_must_fail git config --get section.key >actual 2>error &&
-       grep " line 3 " error
+       test_i18ngrep " line 3 " error
 '
 
 test_expect_success 'barf on incomplete section header' '
@@ -1074,7 +1241,7 @@ test_expect_success 'barf on incomplete section header' '
        key = value
        EOF
        test_must_fail git config --get section.key >actual 2>error &&
-       grep " line 2 " error
+       test_i18ngrep " line 2 " error
 '
 
 test_expect_success 'barf on incomplete string' '
@@ -1084,7 +1251,341 @@ test_expect_success 'barf on incomplete string' '
        key = "value string
        EOF
        test_must_fail git config --get section.key >actual 2>error &&
-       grep " line 3 " error
+       test_i18ngrep " line 3 " error
+'
+
+test_expect_success 'urlmatch' '
+       cat >.git/config <<-\EOF &&
+       [http]
+               sslVerify
+       [http "https://weak.example.com"]
+               sslVerify = false
+               cookieFile = /tmp/cookie.txt
+       EOF
+
+       test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
+       test_must_be_empty actual &&
+
+       echo true >expect &&
+       git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo false >expect &&
+       git config --bool --get-urlmatch http.sslverify https://weak.example.com >actual &&
+       test_cmp expect actual &&
+
+       {
+               echo http.cookiefile /tmp/cookie.txt &&
+               echo http.sslverify false
+       } >expect &&
+       git config --get-urlmatch HTTP https://weak.example.com >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'urlmatch favors more specific URLs' '
+       cat >.git/config <<-\EOF &&
+       [http "https://example.com/"]
+               cookieFile = /tmp/root.txt
+       [http "https://example.com/subdirectory"]
+               cookieFile = /tmp/subdirectory.txt
+       [http "https://user@example.com/"]
+               cookieFile = /tmp/user.txt
+       [http "https://averylonguser@example.com/"]
+               cookieFile = /tmp/averylonguser.txt
+       [http "https://preceding.example.com"]
+               cookieFile = /tmp/preceding.txt
+       [http "https://*.example.com"]
+               cookieFile = /tmp/wildcard.txt
+       [http "https://*.example.com/wildcardwithsubdomain"]
+               cookieFile = /tmp/wildcardwithsubdomain.txt
+       [http "https://trailing.example.com"]
+               cookieFile = /tmp/trailing.txt
+       [http "https://user@*.example.com/"]
+               cookieFile = /tmp/wildcardwithuser.txt
+       [http "https://sub.example.com/"]
+               cookieFile = /tmp/sub.txt
+       EOF
+
+       echo http.cookiefile /tmp/root.txt >expect &&
+       git config --get-urlmatch HTTP https://example.com >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/subdirectory.txt >expect &&
+       git config --get-urlmatch HTTP https://example.com/subdirectory >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/subdirectory.txt >expect &&
+       git config --get-urlmatch HTTP https://example.com/subdirectory/nested >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/user.txt >expect &&
+       git config --get-urlmatch HTTP https://user@example.com/ >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/subdirectory.txt >expect &&
+       git config --get-urlmatch HTTP https://averylonguser@example.com/subdirectory >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/preceding.txt >expect &&
+       git config --get-urlmatch HTTP https://preceding.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/wildcard.txt >expect &&
+       git config --get-urlmatch HTTP https://wildcard.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/sub.txt >expect &&
+       git config --get-urlmatch HTTP https://sub.example.com/wildcardwithsubdomain >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/trailing.txt >expect &&
+       git config --get-urlmatch HTTP https://trailing.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo http.cookiefile /tmp/sub.txt >expect &&
+       git config --get-urlmatch HTTP https://user@sub.example.com >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'urlmatch with wildcard' '
+       cat >.git/config <<-\EOF &&
+       [http]
+               sslVerify
+       [http "https://*.example.com"]
+               sslVerify = false
+               cookieFile = /tmp/cookie.txt
+       EOF
+
+       test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
+       test_must_be_empty actual &&
+
+       echo true >expect &&
+       git config --bool --get-urlmatch http.SSLverify https://example.com >actual &&
+       test_cmp expect actual &&
+
+       echo true >expect &&
+       git config --bool --get-urlmatch http.SSLverify https://good-example.com >actual &&
+       test_cmp expect actual &&
+
+       echo true >expect &&
+       git config --bool --get-urlmatch http.sslverify https://deep.nested.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo false >expect &&
+       git config --bool --get-urlmatch http.sslverify https://good.example.com >actual &&
+       test_cmp expect actual &&
+
+       {
+               echo http.cookiefile /tmp/cookie.txt &&
+               echo http.sslverify false
+       } >expect &&
+       git config --get-urlmatch HTTP https://good.example.com >actual &&
+       test_cmp expect actual &&
+
+       echo http.sslverify >expect &&
+       git config --get-urlmatch HTTP https://more.example.com.au >actual &&
+       test_cmp expect actual
+'
+
+# good section hygiene
+test_expect_failure 'unsetting the last key in a section removes header' '
+       cat >.git/config <<-\EOF &&
+       # some generic comment on the configuration file itself
+       # a comment specific to this "section" section.
+       [section]
+       # some intervening lines
+       # that should also be dropped
+
+       key = value
+       # please be careful when you update the above variable
+       EOF
+
+       cat >expect <<-\EOF &&
+       # some generic comment on the configuration file itself
+       EOF
+
+       git config --unset section.key &&
+       test_cmp expect .git/config
+'
+
+test_expect_failure 'adding a key into an empty section reuses header' '
+       cat >.git/config <<-\EOF &&
+       [section]
+       EOF
+
+       q_to_tab >expect <<-\EOF &&
+       [section]
+       Qkey = value
+       EOF
+
+       git config section.key value &&
+       test_cmp expect .git/config
+'
+
+test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
+       chmod 0600 .git/config &&
+       git config imap.pass Hunter2 &&
+       perl -e \
+         "die q(badset) if ((stat(q(.git/config)))[2] & 07777) != 0600" &&
+       git config --rename-section imap pop &&
+       perl -e \
+         "die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
+'
+
+! test_have_prereq MINGW ||
+HOME="$(pwd)" # convert to Windows path
+
+test_expect_success 'set up --show-origin tests' '
+       INCLUDE_DIR="$HOME/include" &&
+       mkdir -p "$INCLUDE_DIR" &&
+       cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
+               [user]
+                       absolute = include
+       EOF
+       cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
+               [user]
+                       relative = include
+       EOF
+       cat >"$HOME"/.gitconfig <<-EOF &&
+               [user]
+                       global = true
+                       override = global
+               [include]
+                       path = "$INCLUDE_DIR/absolute.include"
+       EOF
+       cat >.git/config <<-\EOF
+               [user]
+                       local = true
+                       override = local
+               [include]
+                       path = ../include/relative.include
+       EOF
+'
+
+test_expect_success '--show-origin with --list' '
+       cat >expect <<-EOF &&
+               file:$HOME/.gitconfig   user.global=true
+               file:$HOME/.gitconfig   user.override=global
+               file:$HOME/.gitconfig   include.path=$INCLUDE_DIR/absolute.include
+               file:$INCLUDE_DIR/absolute.include      user.absolute=include
+               file:.git/config        user.local=true
+               file:.git/config        user.override=local
+               file:.git/config        include.path=../include/relative.include
+               file:.git/../include/relative.include   user.relative=include
+               command line:   user.cmdline=true
+       EOF
+       git -c user.cmdline=true config --list --show-origin >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin with --list --null' '
+       cat >expect <<-EOF &&
+               file:$HOME/.gitconfigQuser.global
+               trueQfile:$HOME/.gitconfigQuser.override
+               globalQfile:$HOME/.gitconfigQinclude.path
+               $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
+               includeQfile:.git/configQuser.local
+               trueQfile:.git/configQuser.override
+               localQfile:.git/configQinclude.path
+               ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
+               includeQcommand line:Quser.cmdline
+               trueQ
+       EOF
+       git -c user.cmdline=true config --null --list --show-origin >output.raw &&
+       nul_to_q <output.raw >output &&
+       # The here-doc above adds a newline that the --null output would not
+       # include. Add it here to make the two comparable.
+       echo >>output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin with single file' '
+       cat >expect <<-\EOF &&
+               file:.git/config        user.local=true
+               file:.git/config        user.override=local
+               file:.git/config        include.path=../include/relative.include
+       EOF
+       git config --local --list --show-origin >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin with --get-regexp' '
+       cat >expect <<-EOF &&
+               file:$HOME/.gitconfig   user.global true
+               file:.git/config        user.local true
+       EOF
+       git config --show-origin --get-regexp "user\.[g|l].*" >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin getting a single key' '
+       cat >expect <<-\EOF &&
+               file:.git/config        local
+       EOF
+       git config --show-origin user.override >output &&
+       test_cmp expect output
+'
+
+test_expect_success 'set up custom config file' '
+       CUSTOM_CONFIG_FILE="file\" (dq) and spaces.conf" &&
+       cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
+               [user]
+                       custom = true
+       EOF
+'
+
+test_expect_success !MINGW '--show-origin escape special file name characters' '
+       cat >expect <<-\EOF &&
+               file:"file\" (dq) and spaces.conf"      user.custom=true
+       EOF
+       git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin' '
+       cat >expect <<-\EOF &&
+               standard input: user.custom=true
+       EOF
+       git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin with file include' '
+       cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
+               [user]
+                       stdin = include
+       EOF
+       cat >expect <<-EOF &&
+               file:$INCLUDE_DIR/stdin.include include
+       EOF
+       echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" \
+               | git config --show-origin --includes --file - user.stdin >output &&
+       test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-origin blob' '
+       cat >expect <<-\EOF &&
+               blob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08   user.custom=true
+       EOF
+       blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+       git config --blob=$blob --show-origin --list >output &&
+       test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-origin blob ref' '
+       cat >expect <<-\EOF &&
+               blob:"master:file\" (dq) and spaces.conf"       user.custom=true
+       EOF
+       git add "$CUSTOM_CONFIG_FILE" &&
+       git commit -m "new config file" &&
+       git config --blob=master:"$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+       test_cmp expect output
+'
+
+test_expect_success '--local requires a repo' '
+       # we expect 128 to ensure that we do not simply
+       # fail to find anything and return code "1"
+       test_expect_code 128 nongit git config --local foo.bar
 '
 
 test_done