Skip to content

Commit 3258258

Browse files
peffgitster
authored andcommitted
config: set up config_source for command-line config
When we parse a config file, we set up the global "cf" variable as a pointer to a "struct config_source" describing the file we are parsing. This is used for error messages, as well as for lookup functions like current_config_name(). The "cf" variable is NULL in two cases: 1. When we are parsing command-line config, in which case there is no source file. 2. When we are not parsing any config at all. Callers like current_config_name() must assume we are in case 1 if they see a NULL "cf". However, this means that if they are accidentally used outside of a config parsing callback, they will quietly return a bogus answer. This might seem like an unlikely accident (why would you ask for the current config file if you are not parsing config?), but it's actually an easy mistake to make due to the configset caching. git_config() serves the answers from a configset cache, and any calls to current_config_name() will claim that we are parsing command-line config, no matter what the original source. So let's distinguish these cases by having the command-line config parser set up a config_source with a NULL name (which callers already handle properly). We can use this to catch programming errors in some cases, and to give better messages to the user in others. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent a77d6db commit 3258258

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

config.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ static int handle_path_include(const char *path, struct config_include_data *inc
131131
if (!access_or_die(path, R_OK, 0)) {
132132
if (++inc->depth > MAX_INCLUDE_DEPTH)
133133
die(include_depth_advice, MAX_INCLUDE_DEPTH, path,
134-
cf && cf->name ? cf->name : "the command line");
134+
!cf ? "<unknown>" :
135+
cf->name ? cf->name :
136+
"the command line");
135137
ret = git_config_from_file(git_config_include, path, inc);
136138
inc->depth--;
137139
}
@@ -210,9 +212,15 @@ int git_config_from_parameters(config_fn_t fn, void *data)
210212
const char **argv = NULL;
211213
int nr = 0, alloc = 0;
212214
int i;
215+
struct config_source source;
213216

214217
if (!env)
215218
return 0;
219+
220+
memset(&source, 0, sizeof(source));
221+
source.prev = cf;
222+
cf = &source;
223+
216224
/* sq_dequote will write over it */
217225
envw = xstrdup(env);
218226

@@ -231,6 +239,7 @@ int git_config_from_parameters(config_fn_t fn, void *data)
231239
out:
232240
free(argv);
233241
free(envw);
242+
cf = source.prev;
234243
return ret;
235244
}
236245

@@ -1341,7 +1350,9 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
13411350
l_item->e = e;
13421351
l_item->value_index = e->value_list.nr - 1;
13431352

1344-
if (cf) {
1353+
if (!cf)
1354+
die("BUG: configset_add_value has no source");
1355+
if (cf->name) {
13451356
kv_info->filename = strintern(cf->name);
13461357
kv_info->linenr = cf->linenr;
13471358
} else {
@@ -2427,10 +2438,14 @@ int parse_config_key(const char *var,
24272438

24282439
const char *current_config_origin_type(void)
24292440
{
2430-
return cf && cf->origin_type ? cf->origin_type : "command line";
2441+
if (!cf)
2442+
die("BUG: current_config_origin_type called outside config callback");
2443+
return cf->origin_type ? cf->origin_type : "command line";
24312444
}
24322445

24332446
const char *current_config_name(void)
24342447
{
2435-
return cf && cf->name ? cf->name : "";
2448+
if (!cf)
2449+
die("BUG: current_config_name called outside config callback");
2450+
return cf->name ? cf->name : "";
24362451
}

0 commit comments

Comments
 (0)