config: always parse GIT_CONFIG_PARAMETERS during git_config

Previously we parsed GIT_CONFIG_PARAMETERS lazily into a
linked list, and then checked that list during future
invocations of git_config. However, that ignores the fact
that the environment variable could change during our run
(e.g., because we parse more "-c" as part of an alias).

Instead, let's just re-parse the environment variable each
time. It's generally not very big, and it's no more work
than parsing the config files, anyway.

As a bonus, we can ditch all of the linked list storage code
entirely, making the code much simpler.

The test unfortunately still does not pass because of an
unrelated bug in handle_options.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2011-05-24 18:49:55 -04:00 committed by Junio C Hamano
parent 5a0c9eeb89
commit 06eb708f33
2 changed files with 18 additions and 40 deletions

View File

@ -20,15 +20,6 @@ static int zlib_compression_seen;
const char *config_exclusive_filename = NULL;
struct config_item
{
struct config_item *next;
char *name;
char *value;
};
static struct config_item *config_parameters;
static struct config_item **config_parameters_tail = &config_parameters;
static void lowercase(char *p)
{
for (; *p; p++)
@ -48,9 +39,9 @@ void git_config_push_parameter(const char *text)
strbuf_release(&env);
}
static int git_config_parse_parameter(const char *text)
static int git_config_parse_parameter(const char *text,
config_fn_t fn, void *data)
{
struct config_item *ct;
struct strbuf tmp = STRBUF_INIT;
struct strbuf **pair;
strbuf_addstr(&tmp, text);
@ -59,23 +50,20 @@ static int git_config_parse_parameter(const char *text)
strbuf_setlen(pair[0], pair[0]->len - 1);
strbuf_trim(pair[0]);
if (!pair[0]->len) {
strbuf_list_free(pair);
return error("bogus config parameter: %s", text);
}
lowercase(pair[0]->buf);
if (fn(pair[0]->buf, pair[1] ? pair[1]->buf : NULL, data) < 0) {
strbuf_list_free(pair);
return -1;
}
ct = xcalloc(1, sizeof(struct config_item));
ct->name = strbuf_detach(pair[0], NULL);
if (pair[1]) {
strbuf_trim(pair[1]);
ct->value = strbuf_detach(pair[1], NULL);
}
strbuf_list_free(pair);
lowercase(ct->name);
*config_parameters_tail = ct;
config_parameters_tail = &ct->next;
return 0;
}
static int git_config_parse_environment(void) {
int git_config_from_parameters(config_fn_t fn, void *data)
{
const char *env = getenv(CONFIG_DATA_ENVIRONMENT);
char *envw;
const char **argv = NULL;
@ -93,8 +81,7 @@ static int git_config_parse_environment(void) {
}
for (i = 0; i < nr; i++) {
if (git_config_parse_parameter(argv[i]) < 0) {
error("bogus config parameter: %s", argv[i]);
if (git_config_parse_parameter(argv[i], fn, data) < 0) {
free(argv);
free(envw);
return -1;
@ -103,7 +90,7 @@ static int git_config_parse_environment(void) {
free(argv);
free(envw);
return 0;
return nr > 0;
}
static int get_next_char(void)
@ -819,22 +806,6 @@ int git_config_global(void)
return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
}
int git_config_from_parameters(config_fn_t fn, void *data)
{
static int loaded_environment;
const struct config_item *ct;
if (!loaded_environment) {
if (git_config_parse_environment() < 0)
return -1;
loaded_environment = 1;
}
for (ct = config_parameters; ct; ct = ct->next)
if (fn(ct->name, ct->value, data) < 0)
return -1;
return config_parameters != NULL;
}
int git_config_early(config_fn_t fn, void *data, const char *repo_config)
{
int ret = 0, found = 0;

View File

@ -854,4 +854,11 @@ test_expect_success 'git -c "key=value" support' '
test_must_fail git -c core.name=value config name
'
test_expect_failure 'git -c works with aliases of builtins' '
git config alias.checkconfig "-c foo.check=bar config foo.check" &&
echo bar >expect &&
git checkconfig >actual &&
test_cmp expect actual
'
test_done