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

[PATCH] git-config: Parse config files leniently

From
Michael J Gruber <git@drmicha.warpmail.net>
Date
Aug 14, 2009, 15:10 UTC
Message-ID
<a812f567b4541ce55e9c60037a047488a0893c36.1250262273.git.git@drmicha.warpmail.net>
In-Reply-To
<A5CDBB91-E889-4849-953A-2C1DB4A04513@gmail.com>

Currently, git config dies as soon as there is a parsing error. This is especially unfortunate in case a user tries to correct config mistakes using git config -e.

Instead, issue a warning only and treat the rest of the line as a comment (ignore it). This benefits not only git config -e users.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Reported-by: David Reitter <david.reitter@gmail.com>
---
The diff and stat are overstatements. I had to shift that whole for loop
by one tab stop but diff (with or without --color-words) does not recognize
this. Nothing inside the loop is changed.
The outer while makes sure that
* we switch to comment mode after a parsing error
* we return eventually no matter whether the file ends with \n or not.
Test had to be adjusted as well.
 config.c                |   80 ++++++++++++++++++++++++----------------------
 t/t1303-wacky-config.sh |    4 +-
 2 files changed, 44 insertions(+), 40 deletions(-)
diff --git a/config.c b/config.c
index e87edea..5e0af5d 100644
--- a/config.c
+++ b/config.c
@@ -207,50 +207,54 @@ static int git_parse_file(config_fn_t fn, void *data)
 	static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
 	const unsigned char *bomptr = utf8_bom;
 
-	for (;;) {
-		int c = get_next_char();
-		if (bomptr && *bomptr) {
-			/* We are at the file beginning; skip UTF8-encoded BOM
-			 * if present. Sane editors won't put this in on their
-			 * own, but e.g. Windows Notepad will do it happily. */
-			if ((unsigned char) c == *bomptr) {
-				bomptr++;
+	while (!config_file_eof) {
+		for (;;) {
+			int c = get_next_char();
+			if (bomptr && *bomptr) {
+				/* We are at the file beginning; skip UTF8-encoded BOM
+				 * if present. Sane editors won't put this in on their
+				 * own, but e.g. Windows Notepad will do it happily. */
+				if ((unsigned char) c == *bomptr) {
+					bomptr++;
+					continue;
+				} else {
+					/* Do not tolerate partial BOM. */
+					if (bomptr != utf8_bom)
+						break;
+					/* No BOM at file beginning. Cool. */
+					bomptr = NULL;
+				}
+			}
+			if (c == '\n') {
+				if (config_file_eof)
+					return 0;
+				comment = 0;
 				continue;
-			} else {
-				/* Do not tolerate partial BOM. */
-				if (bomptr != utf8_bom)
+			}
+			if (comment || isspace(c))
+				continue;
+			if (c == '#' || c == ';') {
+				comment = 1;
+				continue;
+			}
+			if (c == '[') {
+				baselen = get_base_var(var);
+				if (baselen <= 0)
 					break;
-				/* No BOM at file beginning. Cool. */
-				bomptr = NULL;
+				var[baselen++] = '.';
+				var[baselen] = 0;
+				continue;
 			}
-		}
-		if (c == '\n') {
-			if (config_file_eof)
-				return 0;
-			comment = 0;
-			continue;
-		}
-		if (comment || isspace(c))
-			continue;
-		if (c == '#' || c == ';') {
-			comment = 1;
-			continue;
-		}
-		if (c == '[') {
-			baselen = get_base_var(var);
-			if (baselen <= 0)
+			if (!isalpha(c))
+				break;
+			var[baselen] = tolower(c);
+			if (get_value(fn, data, var, baselen+1) < 0)
 				break;
-			var[baselen++] = '.';
-			var[baselen] = 0;
-			continue;
 		}
-		if (!isalpha(c))
-			break;
-		var[baselen] = tolower(c);
-		if (get_value(fn, data, var, baselen+1) < 0)
-			break;
+		warning("bad config file line %d in %s", config_linenr, config_file_name);
+		comment = 1;
 	}
-	die("bad config file line %d in %s", config_linenr, config_file_name);
+	return -1;
 }
 
 static int parse_unit_factor(const char *end, unsigned long *val)
diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh
index 080117c..be850c5 100755
--- a/t/t1303-wacky-config.sh
+++ b/t/t1303-wacky-config.sh
@@ -9,7 +9,7 @@ setup() {
 }
 
 check() {
-	echo "$2" >expected
+	printf "$2\n" >expected
 	git config --get "$1" >actual 2>&1
 	test_cmp actual expected
 }
@@ -44,7 +44,7 @@ LONG_VALUE=$(printf "x%01021dx a" 7)
 test_expect_success 'do not crash on special long config line' '
 	setup &&
 	git config section.key "$LONG_VALUE" &&
-	check section.key "fatal: bad config file line 2 in .git/config"
+	check section.key "warning: bad config file line 2 in .git/config\nwarning: bad config file line 2 in .git/config"
 '
 
 test_done
-- 
1.6.4.225.gb589e
Previous: Jakub NarebskiNext: Junio C Hamano
Message 5 of 14 in “git config -> "fatal: bad config file"”
  1. David ReitterAug 14, 2009
  2. Michael J GruberAug 14, 2009
  3. David ReitterAug 14, 2009
  4. Jakub NarebskiAug 14, 2009
  5. git-config: Parse config files lenientlyMichael J Gruber, Aug 14, 2009
  6. Junio C HamanoAug 14, 2009
  7. Michael J GruberAug 17, 2009
  8. Junio C HamanoAug 17, 2009
  9. [PATCHv2] git-config: Parse config files lenientlyMichael J Gruber, Sep 2, 2009
  10. Junio C HamanoSep 3, 2009
  11. Michael J GruberSep 3, 2009
  12. Junio C HamanoSep 3, 2009
  13. Michael J GruberSep 4, 2009
  14. Junio C HamanoSep 4, 2009

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.