Skip to content

Commit 9e9de18

Browse files
peffgitster
authored andcommitted
config: silence warnings for command names with invalid keys
When we are running the git command "foo", we may have to look up the config keys "pager.foo" and "alias.foo". These config schemes are mis-designed, as the command names can be anything, but the config syntax has some restrictions. For example: $ git foo_bar error: invalid key: pager.foo_bar error: invalid key: alias.foo_bar git: 'foo_bar' is not a git command. See 'git --help'. You cannot name an alias with an underscore. And if you have an external command with one, you cannot configure its pager. In the long run, we may develop a different config scheme for these features. But in the near term (and because we'll need to support the existing scheme indefinitely), we should at least squelch the error messages shown above. These errors come from git_config_parse_key. Ideally we would pass a "quiet" flag to the config machinery, but there are many layers between the pager code and the key parsing. Passing a flag through all of those would be an invasive change. Instead, let's provide a config function to report on whether a key is syntactically valid, and have the pager and alias code skip lookup for bogus keys. We can build this easily around the existing git_config_parse_key, with two minor modifications: 1. We now handle a NULL store_key, to validate but not write out the normalized key. 2. We accept a "quiet" flag to avoid writing to stderr. This doesn't need to be a full-blown public "flags" field, because we can make the existing implementation a static helper function, keeping the mess contained inside config.c. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fdf96a2 commit 9e9de18

File tree

5 files changed

+43
-12
lines changed

5 files changed

+43
-12
lines changed

alias.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ char *alias_lookup(const char *alias)
55
char *v = NULL;
66
struct strbuf key = STRBUF_INIT;
77
strbuf_addf(&key, "alias.%s", alias);
8-
git_config_get_string(key.buf, &v);
8+
if (git_config_key_is_valid(key.buf))
9+
git_config_get_string(key.buf, &v);
910
strbuf_release(&key);
1011
return v;
1112
}

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ extern int git_config_pathname(const char **, const char *, const char *);
13661366
extern int git_config_set_in_file(const char *, const char *, const char *);
13671367
extern int git_config_set(const char *, const char *);
13681368
extern int git_config_parse_key(const char *, char **, int *);
1369+
extern int git_config_key_is_valid(const char *key);
13691370
extern int git_config_set_multivar(const char *, const char *, const char *, int);
13701371
extern int git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int);
13711372
extern int git_config_rename_section(const char *, const char *);

config.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,7 @@ int git_config_set(const char *key, const char *value)
18431843
* baselen - pointer to int which will hold the length of the
18441844
* section + subsection part, can be NULL
18451845
*/
1846-
int git_config_parse_key(const char *key, char **store_key, int *baselen_)
1846+
static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet)
18471847
{
18481848
int i, dot, baselen;
18491849
const char *last_dot = strrchr(key, '.');
@@ -1854,12 +1854,14 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
18541854
*/
18551855

18561856
if (last_dot == NULL || last_dot == key) {
1857-
error("key does not contain a section: %s", key);
1857+
if (!quiet)
1858+
error("key does not contain a section: %s", key);
18581859
return -CONFIG_NO_SECTION_OR_NAME;
18591860
}
18601861

18611862
if (!last_dot[1]) {
1862-
error("key does not contain variable name: %s", key);
1863+
if (!quiet)
1864+
error("key does not contain variable name: %s", key);
18631865
return -CONFIG_NO_SECTION_OR_NAME;
18641866
}
18651867

@@ -1870,7 +1872,8 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
18701872
/*
18711873
* Validate the key and while at it, lower case it for matching.
18721874
*/
1873-
*store_key = xmalloc(strlen(key) + 1);
1875+
if (store_key)
1876+
*store_key = xmalloc(strlen(key) + 1);
18741877

18751878
dot = 0;
18761879
for (i = 0; key[i]; i++) {
@@ -1881,26 +1884,42 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
18811884
if (!dot || i > baselen) {
18821885
if (!iskeychar(c) ||
18831886
(i == baselen + 1 && !isalpha(c))) {
1884-
error("invalid key: %s", key);
1887+
if (!quiet)
1888+
error("invalid key: %s", key);
18851889
goto out_free_ret_1;
18861890
}
18871891
c = tolower(c);
18881892
} else if (c == '\n') {
1889-
error("invalid key (newline): %s", key);
1893+
if (!quiet)
1894+
error("invalid key (newline): %s", key);
18901895
goto out_free_ret_1;
18911896
}
1892-
(*store_key)[i] = c;
1897+
if (store_key)
1898+
(*store_key)[i] = c;
18931899
}
1894-
(*store_key)[i] = 0;
1900+
if (store_key)
1901+
(*store_key)[i] = 0;
18951902

18961903
return 0;
18971904

18981905
out_free_ret_1:
1899-
free(*store_key);
1900-
*store_key = NULL;
1906+
if (store_key) {
1907+
free(*store_key);
1908+
*store_key = NULL;
1909+
}
19011910
return -CONFIG_INVALID_KEY;
19021911
}
19031912

1913+
int git_config_parse_key(const char *key, char **store_key, int *baselen)
1914+
{
1915+
return git_config_parse_key_1(key, store_key, baselen, 0);
1916+
}
1917+
1918+
int git_config_key_is_valid(const char *key)
1919+
{
1920+
return !git_config_parse_key_1(key, NULL, NULL, 1);
1921+
}
1922+
19041923
/*
19051924
* If value==NULL, unset in (remove from) config,
19061925
* if value_regex!=NULL, disregard key/value pairs where value does not match.

pager.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ int check_pager_config(const char *cmd)
149149
struct strbuf key = STRBUF_INIT;
150150
const char *value = NULL;
151151
strbuf_addf(&key, "pager.%s", cmd);
152-
if (!git_config_get_value(key.buf, &value)) {
152+
if (git_config_key_is_valid(key.buf) &&
153+
!git_config_get_value(key.buf, &value)) {
153154
int b = git_config_maybe_bool(key.buf, value);
154155
if (b >= 0)
155156
want = b;

t/t7006-pager.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,4 +447,13 @@ test_expect_success TTY 'external command pagers override sub-commands' '
447447
test_cmp expect actual
448448
'
449449

450+
test_expect_success 'command with underscores does not complain' '
451+
write_script git-under_score <<-\EOF &&
452+
echo ok
453+
EOF
454+
git --exec-path=. under_score >actual 2>&1 &&
455+
echo ok >expect &&
456+
test_cmp expect actual
457+
'
458+
450459
test_done

0 commit comments

Comments
 (0)