git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] config: Add --quoted option to produce machine-parsable output

From
Frank Lichtenheld <frank@lichtenheld.de>
Date
May 21, 2007, 17:46 UTC
Message-ID
<11797696193384-git-send-email-frank@lichtenheld.de>
In-Reply-To
<20070520225953.GK4085@planck.djpig.de>

This option will enclose key names in quotes (") if they contain a subsection and then escape " and \. It will also escape line breaks in values. Together this should produce an easily parsable output.

Affects --list and --get-*
Signed-off-by: Frank Lichtenheld <frank@lichtenheld.de>
---
 builtin-config.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 83 insertions(+), 9 deletions(-)
 Will add asciidoc documentation and test cases if people think that this is
 a good idea.
 I'm writing C about once a year, so I really don't mind being told if it's
 crap ;)
diff --git a/builtin-config.c b/builtin-config.c
index b2515f7..454cf4e 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -2,7 +2,7 @@
 #include "cache.h"
 
 static const char git_config_set_usage[] =
-"git-config [ --global | --system ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+"git-config [ --global | --system ] [ --bool | --int ] [--quoted] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
 
 static char *key;
 static regex_t *key_regexp;
@@ -12,14 +12,73 @@ static int use_key_regexp;
 static int do_all;
 static int do_not_match;
 static int seen;
+static int quoted;
 static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
 
+static char* quote_key(const char *key_)
+{
+	char *pos1, *pos2;
+	char* key_quot;
+
+	pos1 = strchr(key_, '.');
+	pos2 = strrchr(key_, '.');
+	if (pos1 != pos2) { /* has subsection */
+		char* key;
+		key = xmalloc(strlen(key_)*2 + 1);
+		key_quot = key;
+		*key++ = '"';
+		while (*key_) {
+			if (*key_ == '"' || *key_ == '\\')
+				*key++ = '\\';
+			*key++ = *key_++;
+		}
+		*key++ = '"';
+		*key = 0;
+	} else {
+		key_quot = xstrdup(key_);
+	}
+	return key_quot;
+}
+
+static char* quote_value(const char* value_)
+{
+	char *val_quot, *val;
+	val = xmalloc(strlen(value_)*2 + 1);
+	val_quot = val;
+
+	while (*value_) {
+		if (*value_ == '\n') {
+			*val++ = '\\';
+			*val++ = 'n';
+			value_ += 2;
+		} else
+			*val++ = *value_++;
+	}
+	*val = 0;
+
+	return val_quot;
+}
+
 static int show_all_config(const char *key_, const char *value_)
 {
-	if (value_)
-		printf("%s=%s\n", key_, value_);
-	else
-		printf("%s\n", key_);
+	if (!quoted) {
+		if (value_)
+			printf("%s=%s\n", key_, value_);
+		else
+			printf("%s\n", key_);
+	} else {
+		char* key_quot = quote_key(key_);
+
+		if (value_) {
+			char* val_quot = quote_value(value_);
+			printf("%s=%s\n", key_quot, val_quot);
+			free(val_quot);
+		} else
+			printf("%s\n", key_quot);
+
+		free(key_quot);
+	}
+
 	return 0;
 }
 
@@ -38,16 +97,26 @@ static int show_config(const char* key_, const char* value_)
 			  regexec(regexp, (value_?value_:""), 0, NULL, 0)))
 		return 0;
 
-	if (show_keys)
-		printf("%s ", key_);
+	if (show_keys) {
+		if (quoted) {
+			char* key = quote_key(key_);
+			printf("%s ", key);
+			free(key);
+		} else
+			printf("%s ", key_);
+	}
 	if (seen && !do_all)
 		dup_error = 1;
 	if (type == T_INT)
 		sprintf(value, "%d", git_config_int(key_, value_?value_:""));
 	else if (type == T_BOOL)
 		vptr = git_config_bool(key_, value_) ? "true" : "false";
-	else
-		vptr = value_?value_:"";
+	else {
+		if (quoted)
+			vptr = value_?quote_value(value_):"";
+		else
+			vptr = value_?value_:"";
+	}
 	seen++;
 	if (dup_error) {
 		error("More than one value for the key %s: %s",
@@ -56,6 +125,9 @@ static int show_config(const char* key_, const char* value_)
 	else
 		printf("%s\n", vptr);
 
+	if (quoted && value_)
+		free((char *)vptr);
+
 	return 0;
 }
 
@@ -141,6 +213,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 			type = T_INT;
 		else if (!strcmp(argv[1], "--bool"))
 			type = T_BOOL;
+		else if (!strcmp(argv[1], "--quoted"))
+			quoted = 1;
 		else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
 			return git_config(show_all_config);
 		else if (!strcmp(argv[1], "--global")) {
-- 
1.5.2-rc3.GIT
Previous: Petr BaudisNext: Junio C Hamano
Message 3 of 34 in “[RFC] Implementing git config handling in Git.pm”
  1. Frank LichtenheldMay 20, 2007
  2. Petr BaudisMay 20, 2007
  3. config: Add --quoted option to produce machine-parsable outputFrank Lichtenheld, May 21, 2007
  4. Junio C HamanoMay 21, 2007
  5. Johannes SchindelinMay 21, 2007
  6. Junio C HamanoMay 21, 2007
  7. Johannes SchindelinMay 21, 2007
  8. Jan HudecMay 21, 2007
  9. Frank LichtenheldMay 21, 2007
  10. Jakub NarebskiMay 21, 2007
  11. config: Add --null/-z option for null-delimted outputFrank Lichtenheld, Jun 17, 2007
  12. Johannes SchindelinJun 19, 2007
  13. Jakub NarebskiJun 19, 2007
  14. Frank LichtenheldJun 19, 2007
  15. Johannes SchindelinJun 19, 2007
  16. Junio C HamanoJun 19, 2007
  17. Frank LichtenheldJun 19, 2007
  18. Johannes SchindelinJun 19, 2007
  19. David KastrupJun 19, 2007
  20. Jakub NarebskiJun 19, 2007
  21. Frank LichtenheldJun 19, 2007
  22. Johannes SchindelinJun 19, 2007
  23. Frank LichtenheldJun 19, 2007
  24. Johannes SchindelinJun 20, 2007
  25. Jakub NarebskiJun 20, 2007
  26. Jakub NarebskiJun 21, 2007
  27. Frank LichtenheldJun 22, 2007
  28. 1/3 config: Complete documentation of --get-regexpFrank Lichtenheld, Jun 25, 2007
  29. 2/3 config: Change output of --get-regexp for valueless keysFrank Lichtenheld, Jun 25, 2007
  30. Junio C HamanoJun 27, 2007
  31. 3/3 config: Add --null/-z option for null-delimted outputFrank Lichtenheld, Jun 25, 2007
  32. Jakub NarebskiJun 25, 2007
  33. Frank LichtenheldJun 26, 2007
  34. Junio C HamanoJun 27, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.