{"thread":{"id":"28659","subject":"[PATCH] Documentation: update [section.subsection] to reflect what git does","startedAt":"2011-10-12T15:52:06Z","lastAt":"2011-10-19T16:13:02Z","messageCount":13,"participants":["Carlos Martín Nieto","Jeff King","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"177444","messageId":"1318434726-5556-1-git-send-email-cmn@elego.de","threadId":"28659","inReplyTo":null,"subject":"[PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Carlos Martín Nieto","fromEmail":"cmn@elego.de","sentAt":"2011-10-12T15:52:06Z","receivedAt":"2011-10-12T15:52:06Z","isPatch":true,"sender":{"key":"cmn@elego.de","avatar":"https://avatars.githubusercontent.com/u/335443?v=4"},"body":"Using the [section.subsection] syntax, the subsection is transformed\nto lower-case and is matched case sensitively. Say so in the\ndocumentation and mention that you shouldn't be using it anyway.\n\nSigned-off-by: Carlos Martín Nieto <cmn@elego.de>\n---\n\nThis bit me recently when I was creating a parser. See Jeff's\nexplanation here:\nhttp://thread.gmane.org/gmane.comp.version-control.git/179569/focus=180290\n\n Documentation/config.txt |    7 ++++---\n 1 files changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 0658ffb..1212c47 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -45,9 +45,10 @@ lines.  Variables may belong directly to a section or to a given subsection.\n You can have `[section]` if you have `[section \"subsection\"]`, but you\n don't need to.\n \n-There is also a case insensitive alternative `[section.subsection]` syntax.\n-In this syntax, subsection names follow the same restrictions as for section\n-names.\n+There is also a deprecated `[section.subsection]` syntax. With this\n+syntax, the subsection name is converted to lower-case and is also\n+compared case sensitively. These subsection names follow the same\n+restrictions as section names.\n \n All the other lines (and the remainder of the line after the section\n header) are recognized as setting variables, in the form\n-- \n1.7.6.557.gcee4\n"},{"id":"177445","messageId":"20111012162939.GA3055@sigill.intra.peff.net","threadId":"28659","inReplyTo":"1318434726-5556-1-git-send-email-cmn@elego.de","subject":"Re: [PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T16:29:39Z","receivedAt":"2011-10-12T16:29:39Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 12, 2011 at 05:52:06PM +0200, Carlos Martín Nieto wrote:\n\n> -There is also a case insensitive alternative `[section.subsection]` syntax.\n> -In this syntax, subsection names follow the same restrictions as for section\n> -names.\n> +There is also a deprecated `[section.subsection]` syntax. With this\n> +syntax, the subsection name is converted to lower-case and is also\n> +compared case sensitively. These subsection names follow the same\n> +restrictions as section names.\n\nHmm. While technically more correct, I think it is a little more\nconfusing to read. The lower-case canonicalization thing is actually\nused for the other case-insensitive parts, too. So maybe it makes sense\nto describe that in detail, and then just note that\n\"[section.subsection]\" uses the same mechanism.\n\nThe patch below does this, and then the original text in the section you\ntweaked above hopefully makes more sense in the new context.\n\nThe explanation matches what we do now, but it did end up a bit longer\nthan I had hoped. We could make it a lot shorter by:\n\n  1. Canonicalizing the section and key names that the caller gives to\n     git-config.\n\n  2. Not mentioning the \"section.foo\" syntax. We can't canonicalize the\n     subsection in (1) because of this syntax. But we can at least gloss\n     over the detail, and then maybe just mention it much later in the\n     file format. Or even deprecate it.\n\n-- >8 --\nSubject: [PATCH] docs/config: explain case-insensitive matching\n\nWe generally think of key matching as case-insensitive, but\nit's not exactly. It's about canonicalizing one side, and\ncomparing it byte-wise with the canonical key name given to\ngit-config.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n Documentation/git-config.txt |   50 +++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 49 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex e7ecf5d..e92aee9 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -28,7 +28,7 @@ DESCRIPTION\n -----------\n You can query/set/replace/unset options with this command. The name is\n actually the section and the key separated by a dot, and the value will be\n-escaped.\n+escaped. See the section on name matching below.\n \n Multiple lines can be added to an option by using the '--add' option.\n If you want to update or unset an option which can occur on multiple\n@@ -178,6 +178,54 @@ See also <<FILES>>.\n \tOpens an editor to modify the specified config file; either\n \t'--system', '--global', or repository (default).\n \n+\n+NAME MATCHING\n+-------------\n+\n+Configuration key names are matched using an algorithm that allows for\n+partial case sensitivity. Section and key names are read from the config\n+files, canonicalized according to the rules below, and then compared\n+case-sensitively with the input given to git-config. Therefore any\n+callers to git-config should request the canonicalized version of the\n+name. This typically means lowercasing the section and key names, and\n+leaving the subsection (if any) intact. For example, ask for\n+`git config core.eol`, not `git config CoRe.EOL`.\n+\n+The canonicalization rules are:\n+\n+1. Lowercase the section and key names.\n+\n+2. If a literal subsection (like `[section \"foo\"]`) is used, leave it\n+   intact.\n+\n+3. If a non-literal subsection (like `[section.foo]`) is used, lowercase\n+   the subsection.\n+\n+4. Concatenate the resulting section, subsection, and key, separated by\n+   a dot ('.').\n+\n+For example, this configuration file:\n+\n+-----------------------------------------------\n+[CORE]\n+eol = true\n+\n+[branch \"Foo\"]\n+REMOTE = origin\n+\n+[color.DIFF]\n+new = blue\n+-----------------------------------------------\n+\n+would yield the following three canonicalized names:\n+\n+-----------------------------------------------\n+core.eol\n+branch.Foo.remote\n+color.diff.new\n+-----------------------------------------------\n+\n+\n [[FILES]]\n FILES\n -----\n-- \n1.7.7.rc2.21.gb9948\n"},{"id":"177448","messageId":"20111012174643.GA14336@sigill.intra.peff.net","threadId":"28659","inReplyTo":"20111012162939.GA3055@sigill.intra.peff.net","subject":"Re: [PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T17:46:43Z","receivedAt":"2011-10-12T17:46:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 12, 2011 at 12:29:39PM -0400, Jeff King wrote:\n\n> The explanation matches what we do now, but it did end up a bit longer\n> than I had hoped. We could make it a lot shorter by:\n> \n>   1. Canonicalizing the section and key names that the caller gives to\n>      git-config.\n\nHmm. Scratch that. We seem to do this already in my tests. I'll look\nfurther and try to make a better documentation patch.\n\n-Peff\n"},{"id":"177449","messageId":"7v62juayra.fsf@alter.siamese.dyndns.org","threadId":"28659","inReplyTo":"1318434726-5556-1-git-send-email-cmn@elego.de","subject":"Re: [PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-10-12T17:46:49Z","receivedAt":"2011-10-12T17:46:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carlos Martín Nieto <cmn@elego.de> writes:\n\n> This bit me recently when I was creating a parser. See Jeff's\n> explanation here:\n> http://thread.gmane.org/gmane.comp.version-control.git/179569/focus=180290\n\nI think you meant to focus on 180123 but anyway I think the updated text reads\nmuch better.\n\nThanks.\n\n>  Documentation/config.txt |    7 ++++---\n>  1 files changed, 4 insertions(+), 3 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 0658ffb..1212c47 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -45,9 +45,10 @@ lines.  Variables may belong directly to a section or to a given subsection.\n>  You can have `[section]` if you have `[section \"subsection\"]`, but you\n>  don't need to.\n>  \n> -There is also a case insensitive alternative `[section.subsection]` syntax.\n> -In this syntax, subsection names follow the same restrictions as for section\n> -names.\n> +There is also a deprecated `[section.subsection]` syntax. With this\n> +syntax, the subsection name is converted to lower-case and is also\n> +compared case sensitively. These subsection names follow the same\n> +restrictions as section names.\n>  \n>  All the other lines (and the remainder of the line after the section\n>  header) are recognized as setting variables, in the form\n"},{"id":"177456","messageId":"20111012182742.GA14543@sigill.intra.peff.net","threadId":"28659","inReplyTo":"20111012174643.GA14336@sigill.intra.peff.net","subject":"Re: [PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T18:27:42Z","receivedAt":"2011-10-12T18:27:42Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 12, 2011 at 01:46:43PM -0400, Jeff King wrote:\n\n> On Wed, Oct 12, 2011 at 12:29:39PM -0400, Jeff King wrote:\n> \n> > The explanation matches what we do now, but it did end up a bit longer\n> > than I had hoped. We could make it a lot shorter by:\n> > \n> >   1. Canonicalizing the section and key names that the caller gives to\n> >      git-config.\n> \n> Hmm. Scratch that. We seem to do this already in my tests. I'll look\n> further and try to make a better documentation patch.\n\nOK, I was all set to do a patch to git-config for this, but it seems the\ncode is already there.  It's only the subsections which are the sticking\npoint, and those can't be canonicalized, because in most cases we need\nto match them exactly.\n\nIn the process, I did some cleanup and added some new tests to t1300,\nwhich I think are probably worth applying anyway.\n\n  [1/2]: t1300: put git invocations inside test function\n  [2/2]: t1300: test mixed-case variable retrieval\n\n-Peff\n"},{"id":"177457","messageId":"20111012182920.GA18948@sigill.intra.peff.net","threadId":"28659","inReplyTo":"20111012182742.GA14543@sigill.intra.peff.net","subject":"[PATCH 1/2] t1300: put git invocations inside test function","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T18:29:20Z","receivedAt":"2011-10-12T18:29:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"This is a very old script, and did a lot of:\n\n  echo whatever >expect\n  git config foo bar\n  test_expect_success 'cmp .git/config expect'\n\nwhich meant that we didn't actually check that the call to\ngit-config succeeded. Fix this, and while we're at it,\nmodernize the style to use test_cmp.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nThere are still a few 'cp' and 'rm' calls outside of the test functions,\nbut we can generally expect those to work (as we do with the 'cat'\ncalls).\n\n t/t1300-repo-config.sh |  176 +++++++++++++++++++++++++-----------------------\n 1 files changed, 93 insertions(+), 83 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 3e140c1..cf508af 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -7,28 +7,28 @@ test_description='Test git config in different settings'\n \n . ./test-lib.sh\n \n-test -f .git/config && rm .git/config\n-\n-git config core.penguin \"little blue\"\n+test_expect_success 'clear default config' '\n+\trm -f .git/config\n+'\n \n cat > expect << EOF\n [core]\n \tpenguin = little blue\n EOF\n-\n-test_expect_success 'initial' 'cmp .git/config expect'\n-\n-git config Core.Movie BadPhysics\n+test_expect_success 'initial' '\n+\tgit config core.penguin \"little blue\" &&\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [core]\n \tpenguin = little blue\n \tMovie = BadPhysics\n EOF\n-\n-test_expect_success 'mixed case' 'cmp .git/config expect'\n-\n-git config Cores.WhatEver Second\n+test_expect_success 'mixed case' '\n+\tgit config Core.Movie BadPhysics &&\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [core]\n@@ -37,10 +37,10 @@ cat > expect << EOF\n [Cores]\n \tWhatEver = Second\n EOF\n-\n-test_expect_success 'similar section' 'cmp .git/config expect'\n-\n-git config CORE.UPPERCASE true\n+test_expect_success 'similar section' '\n+\tgit config Cores.WhatEver Second\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [core]\n@@ -50,8 +50,10 @@ cat > expect << EOF\n [Cores]\n \tWhatEver = Second\n EOF\n-\n-test_expect_success 'similar section' 'cmp .git/config expect'\n+test_expect_success 'uppercase section' '\n+\tgit config CORE.UPPERCASE true &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'replace with non-match' \\\n \t'git config core.penguin kingpin !blue'\n@@ -69,7 +71,7 @@ cat > expect << EOF\n \tWhatEver = Second\n EOF\n \n-test_expect_success 'non-match result' 'cmp .git/config expect'\n+test_expect_success 'non-match result' 'test_cmp expect .git/config'\n \n cat > .git/config <<\\EOF\n [alpha]\n@@ -88,7 +90,7 @@ bar = foo\n [beta]\n EOF\n \n-test_expect_success 'unset with cont. lines is correct' 'cmp .git/config expect'\n+test_expect_success 'unset with cont. lines is correct' 'test_cmp expect .git/config'\n \n cat > .git/config << EOF\n [beta] ; silly comment # another comment\n@@ -116,7 +118,7 @@ noIndent= sillyValue ; 'nother silly comment\n [nextSection] noNewline = ouch\n EOF\n \n-test_expect_success 'multiple unset is correct' 'cmp .git/config expect'\n+test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config'\n \n cp .git/config2 .git/config\n \n@@ -140,9 +142,7 @@ noIndent= sillyValue ; 'nother silly comment\n [nextSection] noNewline = ouch\n EOF\n \n-test_expect_success 'all replaced' 'cmp .git/config expect'\n-\n-git config beta.haha alpha\n+test_expect_success 'all replaced' 'test_cmp expect .git/config'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -153,10 +153,10 @@ noIndent= sillyValue ; 'nother silly comment\n \thaha = alpha\n [nextSection] noNewline = ouch\n EOF\n-\n-test_expect_success 'really mean test' 'cmp .git/config expect'\n-\n-git config nextsection.nonewline wow\n+test_expect_success 'really mean test' '\n+\tgit config beta.haha alpha &&\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -168,11 +168,12 @@ noIndent= sillyValue ; 'nother silly comment\n [nextSection]\n \tnonewline = wow\n EOF\n-\n-test_expect_success 'really really mean test' 'cmp .git/config expect'\n+test_expect_success 'really really mean test' '\n+\tgit config nextsection.nonewline wow &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'get value' 'test alpha = $(git config beta.haha)'\n-git config --unset beta.haha\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -183,10 +184,10 @@ noIndent= sillyValue ; 'nother silly comment\n [nextSection]\n \tnonewline = wow\n EOF\n-\n-test_expect_success 'unset' 'cmp .git/config expect'\n-\n-git config nextsection.NoNewLine \"wow2 for me\" \"for me$\"\n+test_expect_success 'unset' '\n+\tgit config --unset beta.haha &&\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -198,8 +199,10 @@ noIndent= sillyValue ; 'nother silly comment\n \tnonewline = wow\n \tNoNewLine = wow2 for me\n EOF\n-\n-test_expect_success 'multivar' 'cmp .git/config expect'\n+test_expect_success 'multivar' '\n+\tgit config nextsection.NoNewLine \"wow2 for me\" \"for me$\" &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'non-match' \\\n \t'git config --get nextsection.nonewline !for'\n@@ -214,8 +217,6 @@ test_expect_success 'ambiguous get' '\n test_expect_success 'get multivar' \\\n \t'git config --get-all nextsection.nonewline'\n \n-git config nextsection.nonewline \"wow3\" \"wow$\"\n-\n cat > expect << EOF\n [beta] ; silly comment # another comment\n noIndent= sillyValue ; 'nother silly comment\n@@ -226,8 +227,10 @@ noIndent= sillyValue ; 'nother silly comment\n \tnonewline = wow3\n \tNoNewLine = wow2 for me\n EOF\n-\n-test_expect_success 'multivar replace' 'cmp .git/config expect'\n+test_expect_success 'multivar replace' '\n+\tgit config nextsection.nonewline \"wow3\" \"wow$\" &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'ambiguous value' '\n \ttest_must_fail git config nextsection.nonewline\n@@ -241,8 +244,6 @@ test_expect_success 'invalid unset' '\n \ttest_must_fail git config --unset somesection.nonewline\n '\n \n-git config --unset nextsection.nonewline \"wow3$\"\n-\n cat > expect << EOF\n [beta] ; silly comment # another comment\n noIndent= sillyValue ; 'nother silly comment\n@@ -253,7 +254,10 @@ noIndent= sillyValue ; 'nother silly comment\n \tNoNewLine = wow2 for me\n EOF\n \n-test_expect_success 'multivar unset' 'cmp .git/config expect'\n+test_expect_success 'multivar unset' '\n+\tgit config --unset nextsection.nonewline \"wow3$\" &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla'\n \n@@ -276,7 +280,7 @@ noIndent= sillyValue ; 'nother silly comment\n \tAlpha = beta\n EOF\n \n-test_expect_success 'hierarchical section value' 'cmp .git/config expect'\n+test_expect_success 'hierarchical section value' 'test_cmp expect .git/config'\n \n cat > expect << EOF\n beta.noindent=sillyValue\n@@ -304,15 +308,16 @@ EOF\n test_expect_success '--get-regexp' \\\n \t'git config --get-regexp in > output && cmp output expect'\n \n-git config --add nextsection.nonewline \"wow4 for you\"\n-\n cat > expect << EOF\n wow2 for me\n wow4 for you\n EOF\n \n-test_expect_success '--add' \\\n-\t'git config --get-all nextsection.nonewline > output && cmp output expect'\n+test_expect_success '--add' '\n+\tgit config --add nextsection.nonewline \"wow4 for you\" &&\n+\tgit config --get-all nextsection.nonewline > output &&\n+\ttest_cmp expect output\n+'\n \n cat > .git/config << EOF\n [novalue]\n@@ -361,8 +366,6 @@ cat > .git/config << EOF\n \tc = d\n EOF\n \n-git config a.x y\n-\n cat > expect << EOF\n [a.b]\n \tc = d\n@@ -370,10 +373,10 @@ cat > expect << EOF\n \tx = y\n EOF\n \n-test_expect_success 'new section is partial match of another' 'cmp .git/config expect'\n-\n-git config b.x y\n-git config a.b c\n+test_expect_success 'new section is partial match of another' '\n+\tgit config a.x y &&\n+\ttest_cmp expect .git/config\n+'\n \n cat > expect << EOF\n [a.b]\n@@ -385,7 +388,11 @@ cat > expect << EOF\n \tx = y\n EOF\n \n-test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'\n+test_expect_success 'new variable inserts into proper section' '\n+\tgit config b.x y &&\n+\tgit config a.b c &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \\\n \t'test_must_fail git config --file non-existing-config -l'\n@@ -399,9 +406,10 @@ cat > expect << EOF\n ein.bahn=strasse\n EOF\n \n-GIT_CONFIG=other-config git config -l > output\n-\n-test_expect_success 'alternative GIT_CONFIG' 'cmp output expect'\n+test_expect_success 'alternative GIT_CONFIG' '\n+\tGIT_CONFIG=other-config git config -l >output &&\n+\ttest_cmp expect output\n+'\n \n test_expect_success 'alternative GIT_CONFIG (--file)' \\\n \t'git config --file other-config -l > output && cmp output expect'\n@@ -417,8 +425,6 @@ test_expect_success 'refer config from subdirectory' '\n \n '\n \n-GIT_CONFIG=other-config git config anwohner.park ausweis\n-\n cat > expect << EOF\n [ein]\n \tbahn = strasse\n@@ -426,7 +432,10 @@ cat > expect << EOF\n \tpark = ausweis\n EOF\n \n-test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect'\n+test_expect_success '--set in alternative GIT_CONFIG' '\n+\tGIT_CONFIG=other-config git config anwohner.park ausweis &&\n+\ttest_cmp expect other-config\n+'\n \n cat > .git/config << EOF\n # Hallo\n@@ -531,7 +540,7 @@ test_expect_success 'section ending' '\n \tgit config gitcvs.enabled true &&\n \tgit config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&\n \tgit config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&\n-\tcmp .git/config expect\n+\ttest_cmp expect .git/config\n \n '\n \n@@ -750,13 +759,6 @@ test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '\n \ttest_cmp expect result\n '\n \n-rm .git/config\n-\n-git config quote.leading \" test\"\n-git config quote.ending \"test \"\n-git config quote.semicolon \"test;test\"\n-git config quote.hash \"test#test\"\n-\n cat > expect << EOF\n [quote]\n \tleading = \" test\"\n@@ -764,8 +766,14 @@ cat > expect << EOF\n \tsemicolon = \"test;test\"\n \thash = \"test#test\"\n EOF\n-\n-test_expect_success 'quoting' 'cmp .git/config expect'\n+test_expect_success 'quoting' '\n+\trm .git/config &&\n+\tgit config quote.leading \" test\" &&\n+\tgit config quote.ending \"test \" &&\n+\tgit config quote.semicolon \"test;test\" &&\n+\tgit config quote.hash \"test#test\" &&\n+\ttest_cmp expect .git/config\n+'\n \n test_expect_success 'key with newline' '\n \ttest_must_fail git config \"key.with\n@@ -790,9 +798,10 @@ section.noncont=not continued\n section.quotecont=cont;inued\n EOF\n \n-git config --list > result\n-\n-test_expect_success 'value continued on next line' 'cmp result expect'\n+test_expect_success 'value continued on next line' '\n+\tgit config --list > result &&\n+\tcmp result expect\n+'\n \n cat > .git/config <<\\EOF\n [section \"sub=section\"]\n@@ -813,16 +822,17 @@ barQsection.sub=section.val3\n Qsection.sub=section.val4\n Qsection.sub=section.val5Q\n EOF\n+test_expect_success '--null --list' '\n+\tgit config --null --list | nul_to_q >result &&\n+\techo >>result &&\n+\ttest_cmp expect result\n+'\n \n-git config --null --list | perl -pe 'y/\\000/Q/' > result\n-echo >>result\n-\n-test_expect_success '--null --list' 'cmp result expect'\n-\n-git config --null --get-regexp 'val[0-9]' | perl -pe 'y/\\000/Q/' > result\n-echo >>result\n-\n-test_expect_success '--null --get-regexp' 'cmp result expect'\n+test_expect_success '--null --get-regexp' '\n+\tgit config --null --get-regexp \"val[0-9]\" | nul_to_q >result &&\n+\techo >>result &&\n+\ttest_cmp expect result\n+'\n \n test_expect_success 'inner whitespace kept verbatim' '\n \tgit config section.val \"foo \t  bar\" &&\n-- \n1.7.7.rc2.21.gb9948\n"},{"id":"177458","messageId":"20111012183002.GB18948@sigill.intra.peff.net","threadId":"28659","inReplyTo":"20111012182742.GA14543@sigill.intra.peff.net","subject":"[PATCH 2/2] t1300: test mixed-case variable retrieval","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T18:30:02Z","receivedAt":"2011-10-12T18:30:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"We should be able to ask for a config value both by its\ncanonical all-lowercase name (as git does internally), as\nwell as by random mixed-case (which will be canonicalized by\ngit-config for us).\n\nSubsections are a tricky point, though. Since we have both\n\n  [section \"Foo\"]\n\nand\n\n  [section.Foo]\n\nyou might want git-config to canonicalize the subsection or\nnot, depending on which you are expecting. But there's no\nway to communicate this; git-config sees only the key, and\ndoesn't know which type of section name will be in the\nconfig file.\n\nSo it must leave the subsection intact, and it is up to the\ncaller to provide a canonical version of the subsection if\nthey want to match the latter form.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nI was surprised this wasn't tested anywhere, but I couldn't find any\nsuch place. I think it makes sense to document the desired behavior in\nthe form of a few tests.\n\n t/t1300-repo-config.sh |   27 +++++++++++++++++++++++++++\n 1 files changed, 27 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex cf508af..8a37f96 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -73,6 +73,33 @@ EOF\n \n test_expect_success 'non-match result' 'test_cmp expect .git/config'\n \n+test_expect_success 'find mixed-case key by canonical name' '\n+\techo Second >expect &&\n+\tgit config cores.whatever >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'find mixed-case key by non-canonical name' '\n+\techo Second >expect &&\n+\tgit config CoReS.WhAtEvEr >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'subsections are not canonicalized by git-config' '\n+\tcat >>.git/config <<-\\EOF &&\n+\t[section.SubSection]\n+\tkey = one\n+\t[section \"SubSection\"]\n+\tkey = two\n+\tEOF\n+\techo one >expect &&\n+\tgit config section.subsection.key >actual &&\n+\ttest_cmp expect actual &&\n+\techo two >expect &&\n+\tgit config section.SubSection.key >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat > .git/config <<\\EOF\n [alpha]\n bar = foo\n-- \n1.7.7.rc2.21.gb9948\n"},{"id":"177459","messageId":"20111012183451.GB14543@sigill.intra.peff.net","threadId":"28659","inReplyTo":"1318434726-5556-1-git-send-email-cmn@elego.de","subject":"Re: [PATCH] Documentation: update [section.subsection] to reflect what git does","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-12T18:34:51Z","receivedAt":"2011-10-12T18:34:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 12, 2011 at 05:52:06PM +0200, Carlos Martín Nieto wrote:\n\n> -There is also a case insensitive alternative `[section.subsection]` syntax.\n> -In this syntax, subsection names follow the same restrictions as for section\n> -names.\n> +There is also a deprecated `[section.subsection]` syntax. With this\n> +syntax, the subsection name is converted to lower-case and is also\n> +compared case sensitively. These subsection names follow the same\n> +restrictions as section names.\n\nOK, now having looked thoroughly at the problem again, I agree that your\ndocumentation update is much better than the one I posted earlier\n(technically we could still talk about canonicalizing the subsection\nearlier in git-config(1), but section.foo names are the deprecated\nminority, so it's probably not worth cluttering the page with\nexplanations).\n\nI do think the \"compared case sensitively\" bit is a little confusing\nhere, because it's not clear what is being compared here (as we're quite\ndeep into a discussion of the file format, and away from the git-config\nusage). It might be more clear to say:\n\n  With this syntax, the subsection name is converted to lower-case, and\n  the result is compared case sensitively against the subsection name\n  provided to git-config.\n\nor something like that.\n\n-Peff\n"},{"id":"177474","messageId":"7vpqi281bk.fsf@alter.siamese.dyndns.org","threadId":"28659","inReplyTo":"20111012183002.GB18948@sigill.intra.peff.net","subject":"Re: [PATCH 2/2] t1300: test mixed-case variable retrieval","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-10-12T19:19:43Z","receivedAt":"2011-10-12T19:19:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I was surprised this wasn't tested anywhere, but I couldn't find any\n> such place. I think it makes sense to document the desired behavior in\n> the form of a few tests.\n\nThanks. The patch looks good.\n\nBut oh boy the original test in the old style was ugly....\n"},{"id":"177987","messageId":"4E9E7115.60303@viscovery.net","threadId":"28659","inReplyTo":"20111012182920.GA18948@sigill.intra.peff.net","subject":"Re: [PATCH 1/2] t1300: put git invocations inside test function","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2011-10-19T06:41:25Z","receivedAt":"2011-10-19T06:41:25Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 10/12/2011 20:29, schrieb Jeff King:\n> @@ -750,13 +759,6 @@ test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '\n>  \ttest_cmp expect result\n>  '\n>  \n> -rm .git/config\n> -\n> -git config quote.leading \" test\"\n> -git config quote.ending \"test \"\n> -git config quote.semicolon \"test;test\"\n> -git config quote.hash \"test#test\"\n> -\n>  cat > expect << EOF\n>  [quote]\n>  \tleading = \" test\"\n> @@ -764,8 +766,14 @@ cat > expect << EOF\n>  \tsemicolon = \"test;test\"\n>  \thash = \"test#test\"\n>  EOF\n> -\n> -test_expect_success 'quoting' 'cmp .git/config expect'\n> +test_expect_success 'quoting' '\n> +\trm .git/config &&\n> +\tgit config quote.leading \" test\" &&\n> +\tgit config quote.ending \"test \" &&\n> +\tgit config quote.semicolon \"test;test\" &&\n> +\tgit config quote.hash \"test#test\" &&\n> +\ttest_cmp expect .git/config\n> +'\n\nThis innocently looking hunk fails on Windows, because the preceding tests\nare skipped, and .git/config does not exist. I was tempted to just change\nthis to 'rm -f'. But there are a few other instances of 'rm .git/config'\nin this file that were *not* moved inside the test function.\n\nHow would you like this solved?\n\n- Move this one out again\n- Add -f to just this one\n- Add -f everywhere\n- a combination of the above?\n\n-- Hannes\n"},{"id":"177989","messageId":"7vzkgxcviz.fsf@alter.siamese.dyndns.org","threadId":"28659","inReplyTo":"4E9E7115.60303@viscovery.net","subject":"Re: [PATCH 1/2] t1300: put git invocations inside test function","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-10-19T07:04:04Z","receivedAt":"2011-10-19T07:04:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> This innocently looking hunk fails on Windows, because the preceding tests\n> are skipped, and .git/config does not exist. I was tempted to just change\n> this to 'rm -f'. But there are a few other instances of 'rm .git/config'\n> in this file that were *not* moved inside the test function.\n>\n> How would you like this solved?\n>\n> - Move this one out again\n> - Add -f to just this one\n> - Add -f everywhere\n> - a combination of the above?\n\nProbably \"rm -f .git/config\" to all tests would be the most appropriate,\nas the desire to start from an empty config file is a sign that each test\nwants to be as independent as possible from previous tests.\n\nAn alternative approach to achieve the independence would be to make each\ntest responsible for cleaning up after itself, with test_when_finished,\nbut that won't work for the first one, as the test framework would give\nyou the original one. Besides, that's trying to be cooperative when each\ntest can fail in an unexpected way (after all the purpose of tests is to\nfail when things go wrong). In order to achieve isolation, each test\nprotecting themselves from others, as long as it can be easily and\nreasonably done (e.g. a single \"rm -f\"), is probably far more preferrable\nthan each test trying to clean after itself, risking possible failure to\ndo so.\n"},{"id":"177990","messageId":"4E9E7E22.7010905@viscovery.net","threadId":"28659","inReplyTo":"7vzkgxcviz.fsf@alter.siamese.dyndns.org","subject":"[PATCH] t1300: attempting to remove a non-existent .git/config is not an error","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2011-10-19T07:37:06Z","receivedAt":"2011-10-19T07:37:06Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Johannes Sixt <j6t@kdbg.org>\n\nSince some tests before test number 79 (\"quoting\") are skipped, .git/config\ndoes not exist and 'rm .git/config' fails. Fix this particular case.\n\nWhile at it, move other instance of 'rm .git/config' that occur in this\nfile inside the test function to document that the test cases want to\nprotect themselves from remnants of earlier tests.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n You may think that the justification of this change would be the\n other way round: protect test cases, then incidentally this fixes\n a failure on Windows. But for me it is as described: The motivation\n is the fix for Windows, and without that, the \"protect test cases\"\n part would not have happened. :-)\n\n t/t1300-repo-config.sh |   19 +++++++------------\n 1 files changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex fba5ae0..51caff0 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -558,8 +558,6 @@ EOF\n test_expect_success \"section was removed properly\" \\\n \t\"test_cmp expect .git/config\"\n \n-rm .git/config\n-\n cat > expect << EOF\n [gitcvs]\n \tenabled = true\n@@ -570,6 +568,7 @@ EOF\n \n test_expect_success 'section ending' '\n \n+\trm -f .git/config &&\n \tgit config gitcvs.enabled true &&\n \tgit config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&\n \tgit config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&\n@@ -642,8 +641,6 @@ test_expect_success 'invalid bool (set)' '\n \n \ttest_must_fail git config --bool bool.nobool foobar'\n \n-rm .git/config\n-\n cat > expect <<\\EOF\n [bool]\n \ttrue1 = true\n@@ -658,6 +655,7 @@ EOF\n \n test_expect_success 'set --bool' '\n \n+\trm -f .git/config &&\n \tgit config --bool bool.true1 01 &&\n \tgit config --bool bool.true2 -1 &&\n \tgit config --bool bool.true3 YeS &&\n@@ -668,8 +666,6 @@ test_expect_success 'set --bool' '\n \tgit config --bool bool.false4 FALSE &&\n \tcmp expect .git/config'\n \n-rm .git/config\n-\n cat > expect <<\\EOF\n [int]\n \tval1 = 1\n@@ -679,13 +675,12 @@ EOF\n \n test_expect_success 'set --int' '\n \n+\trm -f .git/config &&\n \tgit config --int int.val1 01 &&\n \tgit config --int int.val2 -1 &&\n \tgit config --int int.val3 5m &&\n \tcmp expect .git/config'\n \n-rm .git/config\n-\n cat >expect <<\\EOF\n [bool]\n \ttrue1 = true\n@@ -699,6 +694,7 @@ cat >expect <<\\EOF\n EOF\n \n test_expect_success 'get --bool-or-int' '\n+\trm -f .git/config &&\n \t(\n \t\techo \"[bool]\"\n \t\techo true1\n@@ -718,7 +714,6 @@ test_expect_success 'get --bool-or-int' '\n \n '\n \n-rm .git/config\n cat >expect <<\\EOF\n [bool]\n \ttrue1 = true\n@@ -732,6 +727,7 @@ cat >expect <<\\EOF\n EOF\n \n test_expect_success 'set --bool-or-int' '\n+\trm -f .git/config &&\n \tgit config --bool-or-int bool.true1 true &&\n \tgit config --bool-or-int bool.false1 false &&\n \tgit config --bool-or-int bool.true2 yes &&\n@@ -742,8 +738,6 @@ test_expect_success 'set --bool-or-int' '\n \ttest_cmp expect .git/config\n '\n \n-rm .git/config\n-\n cat >expect <<\\EOF\n [path]\n \thome = ~/\n@@ -752,6 +746,7 @@ cat >expect <<\\EOF\n EOF\n \n test_expect_success NOT_MINGW 'set --path' '\n+\trm -f .git/config &&\n \tgit config --path path.home \"~/\" &&\n \tgit config --path path.normal \"/dev/null\" &&\n \tgit config --path path.trailingtilde \"foo~\" &&\n@@ -800,7 +795,7 @@ cat > expect << EOF\n \thash = \"test#test\"\n EOF\n test_expect_success 'quoting' '\n-\trm .git/config &&\n+\trm -f .git/config &&\n \tgit config quote.leading \" test\" &&\n \tgit config quote.ending \"test \" &&\n \tgit config quote.semicolon \"test;test\" &&\n-- \n1.7.7.1507.g94722\n"},{"id":"177998","messageId":"20111019161302.GA3157@sigill.intra.peff.net","threadId":"28659","inReplyTo":"4E9E7E22.7010905@viscovery.net","subject":"Re: [PATCH] t1300: attempting to remove a non-existent .git/config is not an error","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-10-19T16:13:02Z","receivedAt":"2011-10-19T16:13:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 19, 2011 at 09:37:06AM +0200, Johannes Sixt wrote:\n\n> From: Johannes Sixt <j6t@kdbg.org>\n> \n> Since some tests before test number 79 (\"quoting\") are skipped, .git/config\n> does not exist and 'rm .git/config' fails. Fix this particular case.\n> \n> While at it, move other instance of 'rm .git/config' that occur in this\n> file inside the test function to document that the test cases want to\n> protect themselves from remnants of earlier tests.\n\nThanks, this fix looks good to me.\n\n-Peff\n"}]}