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>

Jeff King committed May 24, 2011 at 18:49 UTC 06eb708f331f0829081f4f3fb3c465eaae345deb
2 files changed +18 -40
config.c
+11 -40
@@ -20,15 +20,6 @@ static int zlib_compression_seen;
20
21 const char *config_exclusive_filename = NULL;
22
23 -struct config_item
24 -{
25 - struct config_item *next;
26 - char *name;
27 - char *value;
28 -};
29 -static struct config_item *config_parameters;
30 -static struct config_item **config_parameters_tail = &config_parameters;
31 -
23 static void lowercase(char *p)
24 {
25 for (; *p; p++)
@@ -48,9 +39,9 @@ void git_config_push_parameter(const char *text)
39 strbuf_release(&env);
40 }
41
51 -static int git_config_parse_parameter(const char *text)
42 +static int git_config_parse_parameter(const char *text,
43 + config_fn_t fn, void *data)
44 {
53 - struct config_item *ct;
45 struct strbuf tmp = STRBUF_INIT;
46 struct strbuf **pair;
47 strbuf_addstr(&tmp, text);
@@ -60,22 +51,19 @@ static int git_config_parse_parameter(const char *text)
51 strbuf_trim(pair[0]);
52 if (!pair[0]->len) {
53 strbuf_list_free(pair);
63 - return -1;
54 + return error("bogus config parameter: %s", text);
55 }
65 - ct = xcalloc(1, sizeof(struct config_item));
66 - ct->name = strbuf_detach(pair[0], NULL);
67 - if (pair[1]) {
68 - strbuf_trim(pair[1]);
69 - ct->value = strbuf_detach(pair[1], NULL);
56 + lowercase(pair[0]->buf);
57 + if (fn(pair[0]->buf, pair[1] ? pair[1]->buf : NULL, data) < 0) {
58 + strbuf_list_free(pair);
59 + return -1;
60 }
61 strbuf_list_free(pair);
72 - lowercase(ct->name);
73 - *config_parameters_tail = ct;
74 - config_parameters_tail = &ct->next;
62 return 0;
63 }
64
78 -static int git_config_parse_environment(void) {
65 +int git_config_from_parameters(config_fn_t fn, void *data)
66 +{
67 const char *env = getenv(CONFIG_DATA_ENVIRONMENT);
68 char *envw;
69 const char **argv = NULL;
@@ -93,8 +81,7 @@ static int git_config_parse_environment(void) {
81 }
82
83 for (i = 0; i < nr; i++) {
96 - if (git_config_parse_parameter(argv[i]) < 0) {
97 - error("bogus config parameter: %s", argv[i]);
84 + if (git_config_parse_parameter(argv[i], fn, data) < 0) {
85 free(argv);
86 free(envw);
87 return -1;
@@ -103,7 +90,7 @@ static int git_config_parse_environment(void) {
90
91 free(argv);
92 free(envw);
106 - return 0;
93 + return nr > 0;
94 }
95
96 static int get_next_char(void)
@@ -819,22 +806,6 @@ int git_config_global(void)
806 return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
807 }
808
822 -int git_config_from_parameters(config_fn_t fn, void *data)
823 -{
824 - static int loaded_environment;
825 - const struct config_item *ct;
826 -
827 - if (!loaded_environment) {
828 - if (git_config_parse_environment() < 0)
829 - return -1;
830 - loaded_environment = 1;
831 - }
832 - for (ct = config_parameters; ct; ct = ct->next)
833 - if (fn(ct->name, ct->value, data) < 0)
834 - return -1;
835 - return config_parameters != NULL;
836 -}
837 -
809 int git_config_early(config_fn_t fn, void *data, const char *repo_config)
810 {
811 int ret = 0, found = 0;
t/t1300-repo-config.sh
+7
@@ -854,4 +854,11 @@ test_expect_success 'git -c "key=value" support' '
854 test_must_fail git -c core.name=value config name
855 '
856
857 +test_expect_failure 'git -c works with aliases of builtins' '
858 + git config alias.checkconfig "-c foo.check=bar config foo.check" &&
859 + echo bar >expect &&
860 + git checkconfig >actual &&
861 + test_cmp expect actual
862 +'
863 +
864 test_done