Skip to content

Commit 780b994

Browse files
config: improve diagnostic for "set" with missing value
"git config set pull.rebase=false" currently fails with "wrong number of arguments", and the implicit form "git config pull.rebase=false" fails with "invalid key". Neither points at the real problem: the value is missing. Report that directly, and when the argument has the shape "<valid-key>=<value>", also suggest the split form: $ git config set pull.rebase=false error: missing value to set to the variable 'pull.rebase=false' hint: did you mean "git config set pull.rebase false"? When the prefix before "=" is not a valid key, drop the hint: $ git config set foo=bar error: missing value to set to a variable with an invalid name 'foo=bar' Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
1 parent 56a4f3c commit 780b994

2 files changed

Lines changed: 81 additions & 1 deletion

File tree

builtin/config.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#define USE_THE_REPOSITORY_VARIABLE
22
#include "builtin.h"
33
#include "abspath.h"
4+
#include "advice.h"
45
#include "config.h"
56
#include "color.h"
67
#include "date.h"
@@ -210,6 +211,33 @@ static void check_argc(int argc, int min, int max)
210211
exit(129);
211212
}
212213

214+
static int is_valid_key(const char *key)
215+
{
216+
const char *last_dot = strrchr(key, '.');
217+
218+
return last_dot && isalpha(last_dot[1]);
219+
}
220+
221+
static NORETURN void die_missing_set_value(const char *arg)
222+
{
223+
const char *last_dot = strrchr(arg, '.');
224+
const char *eq = last_dot ? strchr(last_dot + 1, '=') : NULL;
225+
char *prefix = eq ? xstrndup(arg, eq - arg) : NULL;
226+
227+
if (prefix && is_valid_key(prefix)) {
228+
error(_("missing value to set to the variable '%s'"), arg);
229+
advise(_("did you mean \"git config set %s %s\"?"),
230+
prefix, eq + 1);
231+
} else if (is_valid_key(arg)) {
232+
error(_("missing value to set to the variable '%s'"), arg);
233+
} else {
234+
error(_("missing value to set to a variable with an invalid name '%s'"),
235+
arg);
236+
}
237+
free(prefix);
238+
exit(129);
239+
}
240+
213241
static void show_config_origin(const struct config_display_options *opts,
214242
const struct key_value_info *kvi,
215243
struct strbuf *buf)
@@ -1133,6 +1161,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix,
11331161

11341162
argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage,
11351163
PARSE_OPT_STOP_AT_NON_OPTION);
1164+
if (argc == 1)
1165+
die_missing_set_value(argv[0]);
11361166
check_argc(argc, 2, 2);
11371167

11381168
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
@@ -1371,6 +1401,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
13711401
};
13721402
char *value = NULL, *comment = NULL;
13731403
int ret = 0;
1404+
int actions_implicit;
13741405
struct key_value_info default_kvi = KVI_INIT;
13751406

13761407
argc = parse_options(argc, argv, prefix, opts,
@@ -1385,7 +1416,8 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
13851416
exit(129);
13861417
}
13871418

1388-
if (actions == 0)
1419+
actions_implicit = (actions == 0);
1420+
if (actions_implicit)
13891421
switch (argc) {
13901422
case 1: actions = ACTION_GET; break;
13911423
case 2: actions = ACTION_SET; break;
@@ -1394,6 +1426,11 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
13941426
error(_("no action specified"));
13951427
exit(129);
13961428
}
1429+
if (actions_implicit && argc == 1) {
1430+
const char *last_dot = strrchr(argv[0], '.');
1431+
if (last_dot && strchr(last_dot + 1, '='))
1432+
die_missing_set_value(argv[0]);
1433+
}
13971434
if (display_opts.omit_values &&
13981435
!(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
13991436
error(_("--name-only is only applicable to --list or --get-regexp"));

t/t1300-config.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,49 @@ test_expect_success 'invalid key' '
469469
test_must_fail git config inval.2key blabla
470470
'
471471

472+
test_expect_success 'set with 1 arg of "key=value": valid key suggests split form' '
473+
test_must_fail git config set pull.rebase=false 2>err &&
474+
test_grep "missing value to set to the variable .pull\\.rebase=false." err &&
475+
test_grep "did you mean .git config set pull\\.rebase false." err
476+
'
477+
478+
test_expect_success 'set with 1 arg of "key=value": implicit form suggests split form' '
479+
test_must_fail git config pull.rebase=false 2>err &&
480+
test_grep "missing value to set to the variable .pull\\.rebase=false." err &&
481+
test_grep "did you mean .git config set pull\\.rebase false." err
482+
'
483+
484+
test_expect_success 'set with 1 arg of "key=value": invalid key does not suggest split form' '
485+
test_must_fail git config set foo=bar 2>err &&
486+
test_grep "missing value to set to a variable with an invalid name .foo=bar." err &&
487+
test_grep ! "did you mean" err
488+
'
489+
490+
test_expect_success 'set with 1 arg: variable name starting with digit is invalid' '
491+
test_must_fail git config set foo.1bar=baz 2>err &&
492+
test_grep "missing value to set to a variable with an invalid name .foo\\.1bar=baz." err &&
493+
test_grep ! "did you mean" err
494+
'
495+
496+
test_expect_success 'set with 1 arg of valid key reports missing value' '
497+
test_must_fail git config set pull.rebase 2>err &&
498+
test_grep "missing value to set to the variable .pull\\.rebase." err &&
499+
test_grep ! "did you mean" err
500+
'
501+
502+
test_expect_success 'set with 2 args including "=" in invalid key does not suggest' '
503+
test_must_fail git config set pull.rebase=false true 2>err &&
504+
test_grep ! "did you mean" err
505+
'
506+
507+
test_expect_success '"=" inside subsection is valid' '
508+
test_when_finished "rm -f subsection.cfg" &&
509+
git config set -f subsection.cfg foo.bar=baz.boo qux &&
510+
echo qux >expect &&
511+
git config get -f subsection.cfg foo.bar=baz.boo >actual &&
512+
test_cmp expect actual
513+
'
514+
472515
test_expect_success 'correct key' '
473516
git config 123456.a123 987
474517
'

0 commit comments

Comments
 (0)