Skip to content

Commit c8deb5a

Browse files
spearcegitster
authored andcommitted
Improve error messages when int/long cannot be parsed from config
If a config file has become mildly corrupted due to a missing LF we may discover some other option joined up against the end of a numeric value. For example: [section] number = 1auto where the "auto" flag was meant to occur on the next line, below "number", but the missing LF has caused it to no longer be its own option. Instead the word "auto" is parsed as a 'unit factor' for the value of "number". Before this change we got the confusing error message: fatal: unknown unit: 'auto' which told us nothing about where the problem appeared. Now we get: fatal: bad config value for 'aninvalid.unit' which at least points the user in the right direction of where to search for the incorrectly formatted configuration file. Noticed by erikh on #git, which received the original error from a simple `git checkout -b` due to a midly corrupted config. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 3a969ef commit c8deb5a

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

config.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,25 +234,34 @@ static int git_parse_file(config_fn_t fn)
234234
die("bad config file line %d in %s", config_linenr, config_file_name);
235235
}
236236

237-
static unsigned long get_unit_factor(const char *end)
237+
static int parse_unit_factor(const char *end, unsigned long *val)
238238
{
239239
if (!*end)
240240
return 1;
241-
else if (!strcasecmp(end, "k"))
242-
return 1024;
243-
else if (!strcasecmp(end, "m"))
244-
return 1024 * 1024;
245-
else if (!strcasecmp(end, "g"))
246-
return 1024 * 1024 * 1024;
247-
die("unknown unit: '%s'", end);
241+
else if (!strcasecmp(end, "k")) {
242+
*val *= 1024;
243+
return 1;
244+
}
245+
else if (!strcasecmp(end, "m")) {
246+
*val *= 1024 * 1024;
247+
return 1;
248+
}
249+
else if (!strcasecmp(end, "g")) {
250+
*val *= 1024 * 1024 * 1024;
251+
return 1;
252+
}
253+
return 0;
248254
}
249255

250256
int git_parse_long(const char *value, long *ret)
251257
{
252258
if (value && *value) {
253259
char *end;
254260
long val = strtol(value, &end, 0);
255-
*ret = val * get_unit_factor(end);
261+
unsigned long factor = 1;
262+
if (!parse_unit_factor(end, &factor))
263+
return 0;
264+
*ret = val * factor;
256265
return 1;
257266
}
258267
return 0;
@@ -263,7 +272,9 @@ int git_parse_ulong(const char *value, unsigned long *ret)
263272
if (value && *value) {
264273
char *end;
265274
unsigned long val = strtoul(value, &end, 0);
266-
*ret = val * get_unit_factor(end);
275+
if (!parse_unit_factor(end, &val))
276+
return 0;
277+
*ret = val;
267278
return 1;
268279
}
269280
return 0;

t/t1300-repo-config.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,23 @@ test_expect_success numbers '
448448
test z1048576 = "z$m"
449449
'
450450

451+
cat > expect <<EOF
452+
fatal: bad config value for 'aninvalid.unit' in .git/config
453+
EOF
454+
455+
test_expect_success 'invalid unit' '
456+
457+
git config aninvalid.unit "1auto" &&
458+
s=$(git config aninvalid.unit) &&
459+
test "z1auto" = "z$s" &&
460+
if git config --int --get aninvalid.unit 2>actual
461+
then
462+
echo config should have failed
463+
false
464+
fi &&
465+
cmp actual expect
466+
'
467+
451468
cat > expect << EOF
452469
true
453470
false

0 commit comments

Comments
 (0)