{"thread":{"id":"2617","subject":"[PATCH] Allow hierarchical section names","startedAt":"2005-11-20T20:22:19Z","lastAt":"2005-11-20T20:22:19Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"12388","messageId":"Pine.LNX.4.63.0511202109160.23849@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2617","inReplyTo":null,"subject":"[PATCH] Allow hierarchical section names","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-20T20:22:19Z","receivedAt":"2005-11-20T20:22:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"A .git/config like follows becomes valid with this patch:\n\n\t[remote.junio]\n\t\turl = git://git.kernel.org/pub/scm/git/git.git\n\t\tpull = master:junio todo:todo +pu:pu\n\n\t[remote.ibook]\n\t\turl = ibook:git/\n\t\tpull = master:ibook\n\t\tpush = master:quetzal\n\n(This patch only does the ini file thing, git-fetch and friends still\nignore these values).\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tNote that -- since don't favor that approach -- this patch\n\tdoes *not* allow for \"citing hierarchies\" like this:\n\n\t\t[Tyrannosaurus.rex]\n\t\t\tjaw = big\n\t\t[.minor]\n\t\t\tjaw = unknown\n\n\ti.e. the complete key of the second entry would be \".minor.jaw\",\n\tnot \"Tyrannosaurus.minor.jaw\".\n\n config.c              |   19 ++++++++++---------\n t/t1300-config-set.sh |   19 +++++++++++++++++++\n 2 files changed, 29 insertions(+), 9 deletions(-)\n\napplies-to: b86aaa1512dbd810af049ec0611604272ac731e7\nff7acdf861ddcb9ff385476c68d35777469494bc\ndiff --git a/config.c b/config.c\nindex 5d237c8..38c0edd 100644\n--- a/config.c\n+++ b/config.c\n@@ -143,7 +143,7 @@ static int get_base_var(char *name)\n \t\t\treturn -1;\n \t\tif (c == ']')\n \t\t\treturn baselen;\n-\t\tif (!isalnum(c))\n+\t\tif (!isalnum(c) && c != '.')\n \t\t\treturn -1;\n \t\tif (baselen > MAXNAME / 2)\n \t\t\treturn -1;\n@@ -405,28 +405,29 @@ int git_config_set_multivar(const char* \n \tint fd;\n \tchar* config_file = strdup(git_path(\"config\"));\n \tchar* lock_file = strdup(git_path(\"config.lock\"));\n-\n-\tstore.multi_replace = multi_replace;\n+\tconst char* last_dot = strrchr(key, '.');\n \n \t/*\n \t * Since \"key\" actually contains the section name and the real\n \t * key name separated by a dot, we have to know where the dot is.\n \t */\n-\tfor (store.baselen = 0;\n-\t\t\tkey[store.baselen] != '.' && key[store.baselen];\n-\t\t\tstore.baselen++);\n-\tif (!key[store.baselen] || !key[store.baselen+1]) {\n+\n+\tif (last_dot == NULL) {\t\n \t\tfprintf(stderr, \"key does not contain a section: %s\\n\", key);\n \t\treturn 2;\n \t}\n+\tstore.baselen = last_dot - key;\n+\n+\tstore.multi_replace = multi_replace;\n \n \t/*\n \t * Validate the key and while at it, lower case it for matching.\n \t */\n \tstore.key = (char*)malloc(strlen(key)+1);\n \tfor (i = 0; key[i]; i++)\n-\t\tif (i != store.baselen && (!isalnum(key[i]) ||\n-\t\t\t\t(i == store.baselen+1 && !isalpha(key[i])))) {\n+\t\tif (i != store.baselen &&\n+\t\t\t\t((!isalnum(key[i]) && key[i] != '.') ||\n+\t\t\t\t (i == store.baselen+1 && !isalpha(key[i])))) {\n \t\t\tfprintf(stderr, \"invalid key: %s\\n\", key);\n \t\t\tfree(store.key);\n \t\t\treturn 1;\ndiff --git a/t/t1300-config-set.sh b/t/t1300-config-set.sh\nindex 59b6c4c..7a5849a 100644\n--- a/t/t1300-config-set.sh\n+++ b/t/t1300-config-set.sh\n@@ -248,5 +248,24 @@ test_expect_failure 'invalid key' 'git-c\n \n test_expect_success 'correct key' 'git-config-set 123456.a123 987'\n \n+test_expect_success 'hierarchical section' \\\n+\t'git-config-set 1.2.3.alpha beta'\n+\n+cat > expect << EOF\n+[beta] ; silly comment # another comment\n+noIndent= sillyValue ; 'nother silly comment\n+\n+# empty line\n+\t\t; comment\n+[nextSection]\n+\tNoNewLine = wow2 for me\n+[123456]\n+\ta123 = 987\n+[1.2.3]\n+\talpha = beta\n+EOF\n+\n+test_expect_success 'hierarchical section value' 'cmp .git/config expect'\n+\n test_done\n \n---\n0.99.9.GIT\n"}]}