Commit 9d7a75be7c66cd5c7931db620b97cbd6525b626f

Patrick Steinhardt 2017-08-25T19:15:00

config_file: make repo and config path accessible to reader The reader machinery will be extended to handle conditional includes. The only conditions that currently exist all match the against the git directory of the repository the config file belongs to. As such, we need to have access to the repository when reading configuration files to properly handle these conditions. One specialty of thes conditional includes is that the actual pattern may also be a relative pattern starting with "./". In this case, we have to match the pattern against the path relative to the config file which is currently being parsed. So besides the repository, we also have to pass down the path to the current config file that is being parsed.

diff --git a/src/config_file.c b/src/config_file.c
index 0a15ca5..800e584 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -120,7 +120,7 @@ typedef struct {
 	diskfile_backend *snapshot_from;
 } diskfile_readonly_backend;
 
-static int config_read(git_strmap *values, struct config_file *file, git_config_level_t level, int depth);
+static int config_read(const git_repository *repo, git_strmap *values, struct config_file *file, git_config_level_t level, int depth);
 static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
 static char *escape_value(const char *ptr);
 
@@ -297,7 +297,7 @@ static int config_open(git_config_backend *cfg, git_config_level_t level, const 
 	if (!git_path_exists(b->file.path))
 		return 0;
 
-	if (res < 0 || (res = config_read(b->header.values->values, &b->file, level, 0)) < 0) {
+	if (res < 0 || (res = config_read(repo, b->header.values->values, &b->file, level, 0)) < 0) {
 		refcounted_strmap_free(b->header.values);
 		b->header.values = NULL;
 	}
@@ -361,7 +361,7 @@ static int config_refresh(git_config_backend *cfg)
 	}
 	git_array_clear(b->file.includes);
 
-	if ((error = config_read(values->values, &b->file, b->level, 0)) < 0)
+	if ((error = config_read(b->repo, values->values, &b->file, b->level, 0)) < 0)
 		goto out;
 
 	if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
@@ -1571,6 +1571,8 @@ static int config_parse(
 }
 
 struct parse_data {
+	const git_repository *repo;
+	const char *file_path;
 	git_strmap *values;
 	git_config_level_t level;
 	int depth;
@@ -1599,7 +1601,8 @@ static int parse_include(struct reader *reader,
 	git_array_init(include->includes);
 	include->path = git_buf_detach(&path);
 
-	result = config_read(parse_data->values, include, parse_data->level, parse_data->depth+1);
+	result = config_read(parse_data->repo, parse_data->values,
+		include, parse_data->level, parse_data->depth+1);
 
 	if (result == GIT_ENOTFOUND) {
 		giterr_clear();
@@ -1657,7 +1660,11 @@ static int read_on_variable(
 	return result;
 }
 
-static int config_read(git_strmap *values, struct config_file *file, git_config_level_t level, int depth)
+static int config_read(const git_repository *repo,
+	git_strmap *values,
+	struct config_file *file,
+	git_config_level_t level,
+	int depth)
 {
 	struct parse_data parse_data;
 	struct reader reader;
@@ -1686,6 +1693,8 @@ static int config_read(git_strmap *values, struct config_file *file, git_config_
 	if (*reader.read_ptr == '\0')
 		goto out;
 
+	parse_data.repo = repo;
+	parse_data.file_path = file->path;
 	parse_data.values = values;
 	parse_data.level = level;
 	parse_data.depth = depth;