DORMANTno replies

[PATCH] Allow hierarchical section names

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:42:12
Subsystem: the rest · Maintainer: Linus Torvalds

A .git/config like follows becomes valid with this patch:

	[remote.junio]
		url = git://git.kernel.org/pub/scm/git/git.git
		pull = master:junio todo:todo +pu:pu

	[remote.ibook]
		url = ibook:git/
		pull = master:ibook
		push = master:quetzal

(This patch only does the ini file thing, git-fetch and friends still
ignore these values).

Signed-off-by: Johannes Schindelin <redacted>

---

	Note that -- since don't favor that approach -- this patch
	does *not* allow for "citing hierarchies" like this:

		[Tyrannosaurus.rex]
			jaw = big
		[.minor]
			jaw = unknown

	i.e. the complete key of the second entry would be ".minor.jaw",
	not "Tyrannosaurus.minor.jaw".

 config.c              |   19 ++++++++++---------
 t/t1300-config-set.sh |   19 +++++++++++++++++++
 2 files changed, 29 insertions(+), 9 deletions(-)

applies-to: b86aaa1512dbd810af049ec0611604272ac731e7
ff7acdf861ddcb9ff385476c68d35777469494bc
diff --git a/config.c b/config.c
index 5d237c8..38c0edd 100644
--- a/config.c
+++ b/config.c
@@ -143,7 +143,7 @@ static int get_base_var(char *name)
 			return -1;
 		if (c == ']')
 			return baselen;
-		if (!isalnum(c))
+		if (!isalnum(c) && c != '.')
 			return -1;
 		if (baselen > MAXNAME / 2)
 			return -1;
@@ -405,28 +405,29 @@ int git_config_set_multivar(const char* 
 	int fd;
 	char* config_file = strdup(git_path("config"));
 	char* lock_file = strdup(git_path("config.lock"));
-
-	store.multi_replace = multi_replace;
+	const char* last_dot = strrchr(key, '.');
 
 	/*
 	 * Since "key" actually contains the section name and the real
 	 * key name separated by a dot, we have to know where the dot is.
 	 */
-	for (store.baselen = 0;
-			key[store.baselen] != '.' && key[store.baselen];
-			store.baselen++);
-	if (!key[store.baselen] || !key[store.baselen+1]) {
+
+	if (last_dot == NULL) {	
 		fprintf(stderr, "key does not contain a section: %s\n", key);
 		return 2;
 	}
+	store.baselen = last_dot - key;
+
+	store.multi_replace = multi_replace;
 
 	/*
 	 * Validate the key and while at it, lower case it for matching.
 	 */
 	store.key = (char*)malloc(strlen(key)+1);
 	for (i = 0; key[i]; i++)
-		if (i != store.baselen && (!isalnum(key[i]) ||
-				(i == store.baselen+1 && !isalpha(key[i])))) {
+		if (i != store.baselen &&
+				((!isalnum(key[i]) && key[i] != '.') ||
+				 (i == store.baselen+1 && !isalpha(key[i])))) {
 			fprintf(stderr, "invalid key: %s\n", key);
 			free(store.key);
 			return 1;
diff --git a/t/t1300-config-set.sh b/t/t1300-config-set.sh
index 59b6c4c..7a5849a 100644
--- a/t/t1300-config-set.sh
+++ b/t/t1300-config-set.sh
@@ -248,5 +248,24 @@ test_expect_failure 'invalid key' 'git-c
 
 test_expect_success 'correct key' 'git-config-set 123456.a123 987'
 
+test_expect_success 'hierarchical section' \
+	'git-config-set 1.2.3.alpha beta'
+
+cat > expect << EOF
+[beta] ; silly comment # another comment
+noIndent= sillyValue ; 'nother silly comment
+
+# empty line
+		; comment
+[nextSection]
+	NoNewLine = wow2 for me
+[123456]
+	a123 = 987
+[1.2.3]
+	alpha = beta
+EOF
+
+test_expect_success 'hierarchical section value' 'cmp .git/config expect'
+
 test_done
 
---
0.99.9.GIT
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help