config: add kvi.path, use it to evaluate includes
Include directives are evaluated using the path of the config file. To reduce the dependence on "config_reader.source", add a new "key_value_info.path" member and use that instead of "config_source.path". This allows us to remove a "struct config_reader *" field from "struct config_include_data", which will subsequently allow us to remove "struct config_reader" entirely. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
f6c213a0cb
commit
908857a9f8
40
config.c
40
config.c
@@ -162,7 +162,6 @@ struct config_include_data {
|
|||||||
const struct config_options *opts;
|
const struct config_options *opts;
|
||||||
struct git_config_source *config_source;
|
struct git_config_source *config_source;
|
||||||
struct repository *repo;
|
struct repository *repo;
|
||||||
struct config_reader *config_reader;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All remote URLs discovered when reading all config files.
|
* All remote URLs discovered when reading all config files.
|
||||||
@@ -181,8 +180,7 @@ static const char include_depth_advice[] = N_(
|
|||||||
"from\n"
|
"from\n"
|
||||||
" %s\n"
|
" %s\n"
|
||||||
"This might be due to circular includes.");
|
"This might be due to circular includes.");
|
||||||
static int handle_path_include(struct config_source *cs,
|
static int handle_path_include(const struct key_value_info *kvi,
|
||||||
const struct key_value_info *kvi,
|
|
||||||
const char *path,
|
const char *path,
|
||||||
struct config_include_data *inc)
|
struct config_include_data *inc)
|
||||||
{
|
{
|
||||||
@@ -205,14 +203,14 @@ static int handle_path_include(struct config_source *cs,
|
|||||||
if (!is_absolute_path(path)) {
|
if (!is_absolute_path(path)) {
|
||||||
char *slash;
|
char *slash;
|
||||||
|
|
||||||
if (!cs || !cs->path) {
|
if (!kvi || !kvi->path) {
|
||||||
ret = error(_("relative config includes must come from files"));
|
ret = error(_("relative config includes must come from files"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
slash = find_last_dir_sep(cs->path);
|
slash = find_last_dir_sep(kvi->path);
|
||||||
if (slash)
|
if (slash)
|
||||||
strbuf_add(&buf, cs->path, slash - cs->path + 1);
|
strbuf_add(&buf, kvi->path, slash - kvi->path + 1);
|
||||||
strbuf_addstr(&buf, path);
|
strbuf_addstr(&buf, path);
|
||||||
path = buf.buf;
|
path = buf.buf;
|
||||||
}
|
}
|
||||||
@@ -220,8 +218,8 @@ static int handle_path_include(struct config_source *cs,
|
|||||||
if (!access_or_die(path, R_OK, 0)) {
|
if (!access_or_die(path, R_OK, 0)) {
|
||||||
if (++inc->depth > MAX_INCLUDE_DEPTH)
|
if (++inc->depth > MAX_INCLUDE_DEPTH)
|
||||||
die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path,
|
die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path,
|
||||||
!cs ? "<unknown>" :
|
!kvi ? "<unknown>" :
|
||||||
cs->name ? cs->name :
|
kvi->filename ? kvi->filename :
|
||||||
"the command line");
|
"the command line");
|
||||||
ret = git_config_from_file_with_options(git_config_include, path, inc,
|
ret = git_config_from_file_with_options(git_config_include, path, inc,
|
||||||
kvi->scope, NULL);
|
kvi->scope, NULL);
|
||||||
@@ -239,7 +237,7 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat)
|
|||||||
strbuf_addstr(pat, "**");
|
strbuf_addstr(pat, "**");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepare_include_condition_pattern(struct config_source *cs,
|
static int prepare_include_condition_pattern(const struct key_value_info *kvi,
|
||||||
struct strbuf *pat)
|
struct strbuf *pat)
|
||||||
{
|
{
|
||||||
struct strbuf path = STRBUF_INIT;
|
struct strbuf path = STRBUF_INIT;
|
||||||
@@ -256,11 +254,11 @@ static int prepare_include_condition_pattern(struct config_source *cs,
|
|||||||
if (pat->buf[0] == '.' && is_dir_sep(pat->buf[1])) {
|
if (pat->buf[0] == '.' && is_dir_sep(pat->buf[1])) {
|
||||||
const char *slash;
|
const char *slash;
|
||||||
|
|
||||||
if (!cs || !cs->path)
|
if (!kvi || !kvi->path)
|
||||||
return error(_("relative config include "
|
return error(_("relative config include "
|
||||||
"conditionals must come from files"));
|
"conditionals must come from files"));
|
||||||
|
|
||||||
strbuf_realpath(&path, cs->path, 1);
|
strbuf_realpath(&path, kvi->path, 1);
|
||||||
slash = find_last_dir_sep(path.buf);
|
slash = find_last_dir_sep(path.buf);
|
||||||
if (!slash)
|
if (!slash)
|
||||||
BUG("how is this possible?");
|
BUG("how is this possible?");
|
||||||
@@ -275,7 +273,7 @@ static int prepare_include_condition_pattern(struct config_source *cs,
|
|||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int include_by_gitdir(struct config_source *cs,
|
static int include_by_gitdir(const struct key_value_info *kvi,
|
||||||
const struct config_options *opts,
|
const struct config_options *opts,
|
||||||
const char *cond, size_t cond_len, int icase)
|
const char *cond, size_t cond_len, int icase)
|
||||||
{
|
{
|
||||||
@@ -292,7 +290,7 @@ static int include_by_gitdir(struct config_source *cs,
|
|||||||
|
|
||||||
strbuf_realpath(&text, git_dir, 1);
|
strbuf_realpath(&text, git_dir, 1);
|
||||||
strbuf_add(&pattern, cond, cond_len);
|
strbuf_add(&pattern, cond, cond_len);
|
||||||
prefix = prepare_include_condition_pattern(cs, &pattern);
|
prefix = prepare_include_condition_pattern(kvi, &pattern);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (prefix < 0)
|
if (prefix < 0)
|
||||||
@@ -428,16 +426,16 @@ static int include_by_remote_url(struct config_include_data *inc,
|
|||||||
inc->remote_urls);
|
inc->remote_urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int include_condition_is_true(struct config_source *cs,
|
static int include_condition_is_true(const struct key_value_info *kvi,
|
||||||
struct config_include_data *inc,
|
struct config_include_data *inc,
|
||||||
const char *cond, size_t cond_len)
|
const char *cond, size_t cond_len)
|
||||||
{
|
{
|
||||||
const struct config_options *opts = inc->opts;
|
const struct config_options *opts = inc->opts;
|
||||||
|
|
||||||
if (skip_prefix_mem(cond, cond_len, "gitdir:", &cond, &cond_len))
|
if (skip_prefix_mem(cond, cond_len, "gitdir:", &cond, &cond_len))
|
||||||
return include_by_gitdir(cs, opts, cond, cond_len, 0);
|
return include_by_gitdir(kvi, opts, cond, cond_len, 0);
|
||||||
else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
|
else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
|
||||||
return include_by_gitdir(cs, opts, cond, cond_len, 1);
|
return include_by_gitdir(kvi, opts, cond, cond_len, 1);
|
||||||
else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
|
else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
|
||||||
return include_by_branch(cond, cond_len);
|
return include_by_branch(cond, cond_len);
|
||||||
else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
|
else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
|
||||||
@@ -453,7 +451,6 @@ static int git_config_include(const char *var, const char *value,
|
|||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct config_include_data *inc = data;
|
struct config_include_data *inc = data;
|
||||||
struct config_source *cs = inc->config_reader->source;
|
|
||||||
const char *cond, *key;
|
const char *cond, *key;
|
||||||
size_t cond_len;
|
size_t cond_len;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -467,16 +464,16 @@ static int git_config_include(const char *var, const char *value,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!strcmp(var, "include.path"))
|
if (!strcmp(var, "include.path"))
|
||||||
ret = handle_path_include(cs, ctx->kvi, value, inc);
|
ret = handle_path_include(ctx->kvi, value, inc);
|
||||||
|
|
||||||
if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) &&
|
if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) &&
|
||||||
cond && include_condition_is_true(cs, inc, cond, cond_len) &&
|
cond && include_condition_is_true(ctx->kvi, inc, cond, cond_len) &&
|
||||||
!strcmp(key, "path")) {
|
!strcmp(key, "path")) {
|
||||||
config_fn_t old_fn = inc->fn;
|
config_fn_t old_fn = inc->fn;
|
||||||
|
|
||||||
if (inc->opts->unconditional_remote_url)
|
if (inc->opts->unconditional_remote_url)
|
||||||
inc->fn = forbid_remote_url;
|
inc->fn = forbid_remote_url;
|
||||||
ret = handle_path_include(cs, ctx->kvi, value, inc);
|
ret = handle_path_include(ctx->kvi, value, inc);
|
||||||
inc->fn = old_fn;
|
inc->fn = old_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,6 +658,7 @@ void kvi_from_param(struct key_value_info *out)
|
|||||||
out->linenr = -1;
|
out->linenr = -1;
|
||||||
out->origin_type = CONFIG_ORIGIN_CMDLINE;
|
out->origin_type = CONFIG_ORIGIN_CMDLINE;
|
||||||
out->scope = CONFIG_SCOPE_COMMAND;
|
out->scope = CONFIG_SCOPE_COMMAND;
|
||||||
|
out->path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_config_parse_parameter(const char *text,
|
int git_config_parse_parameter(const char *text,
|
||||||
@@ -1064,6 +1062,7 @@ static void kvi_from_source(struct config_source *cs,
|
|||||||
out->origin_type = cs->origin_type;
|
out->origin_type = cs->origin_type;
|
||||||
out->linenr = cs->linenr;
|
out->linenr = cs->linenr;
|
||||||
out->scope = scope;
|
out->scope = scope;
|
||||||
|
out->path = cs->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int git_parse_source(struct config_source *cs, config_fn_t fn,
|
static int git_parse_source(struct config_source *cs, config_fn_t fn,
|
||||||
@@ -2282,7 +2281,6 @@ int config_with_options(config_fn_t fn, void *data,
|
|||||||
inc.opts = opts;
|
inc.opts = opts;
|
||||||
inc.repo = repo;
|
inc.repo = repo;
|
||||||
inc.config_source = config_source;
|
inc.config_source = config_source;
|
||||||
inc.config_reader = &the_reader;
|
|
||||||
fn = git_config_include;
|
fn = git_config_include;
|
||||||
data = &inc;
|
data = &inc;
|
||||||
}
|
}
|
||||||
|
|||||||
2
config.h
2
config.h
@@ -116,12 +116,14 @@ struct key_value_info {
|
|||||||
int linenr;
|
int linenr;
|
||||||
enum config_origin_type origin_type;
|
enum config_origin_type origin_type;
|
||||||
enum config_scope scope;
|
enum config_scope scope;
|
||||||
|
const char *path;
|
||||||
};
|
};
|
||||||
#define KVI_INIT { \
|
#define KVI_INIT { \
|
||||||
.filename = NULL, \
|
.filename = NULL, \
|
||||||
.linenr = -1, \
|
.linenr = -1, \
|
||||||
.origin_type = CONFIG_ORIGIN_UNKNOWN, \
|
.origin_type = CONFIG_ORIGIN_UNKNOWN, \
|
||||||
.scope = CONFIG_SCOPE_UNKNOWN, \
|
.scope = CONFIG_SCOPE_UNKNOWN, \
|
||||||
|
.path = NULL, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Captures additional information that a config callback can use. */
|
/* Captures additional information that a config callback can use. */
|
||||||
|
|||||||
Reference in New Issue
Block a user