summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h11
-rw-r--r--config.c23
-rw-r--r--t/helper/test-config.c16
-rwxr-xr-xt/t1308-config-set.sh3
4 files changed, 53 insertions, 0 deletions
diff --git a/cache.h b/cache.h
index 1bce212e88..2e3b377ae8 100644
--- a/cache.h
+++ b/cache.h
@@ -1604,6 +1604,16 @@ extern const char *get_log_output_encoding(void);
extern const char *get_commit_output_encoding(void);
extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
+
+enum config_scope {
+ CONFIG_SCOPE_UNKNOWN = 0,
+ CONFIG_SCOPE_SYSTEM,
+ CONFIG_SCOPE_GLOBAL,
+ CONFIG_SCOPE_REPO,
+ CONFIG_SCOPE_CMDLINE,
+};
+
+extern enum config_scope current_config_scope(void);
extern const char *current_config_origin_type(void);
extern const char *current_config_name(void);
@@ -1697,6 +1707,7 @@ struct key_value_info {
const char *filename;
int linenr;
const char *origin_type;
+ enum config_scope scope;
};
extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3)));
diff --git a/config.c b/config.c
index d555deeb9a..87629164b3 100644
--- a/config.c
+++ b/config.c
@@ -57,6 +57,15 @@ struct config_source {
static struct config_source *cf;
static struct key_value_info *current_config_kvi;
+/*
+ * Similar to the variables above, this gives access to the "scope" of the
+ * current value (repo, global, etc). For cached values, it can be found via
+ * the current_config_kvi as above. During parsing, the current value can be
+ * found in this variable. It's not part of "cf" because it transcends a single
+ * file (i.e., a file included from .git/config is still in "repo" scope).
+ */
+static enum config_scope current_parsing_scope;
+
static int zlib_compression_seen;
/*
@@ -1229,22 +1238,27 @@ static int do_git_config_sequence(config_fn_t fn, void *data)
char *user_config = expand_user_path("~/.gitconfig");
char *repo_config = git_pathdup("config");
+ current_parsing_scope = CONFIG_SCOPE_SYSTEM;
if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0))
ret += git_config_from_file(fn, git_etc_gitconfig(),
data);
+ current_parsing_scope = CONFIG_SCOPE_GLOBAL;
if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
ret += git_config_from_file(fn, xdg_config, data);
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
ret += git_config_from_file(fn, user_config, data);
+ current_parsing_scope = CONFIG_SCOPE_REPO;
if (repo_config && !access_or_die(repo_config, R_OK, 0))
ret += git_config_from_file(fn, repo_config, data);
+ current_parsing_scope = CONFIG_SCOPE_CMDLINE;
if (git_config_from_parameters(fn, data) < 0)
die(_("unable to parse command-line config"));
+ current_parsing_scope = CONFIG_SCOPE_UNKNOWN;
free(xdg_config);
free(user_config);
free(repo_config);
@@ -1383,6 +1397,7 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
kv_info->linenr = -1;
kv_info->origin_type = NULL;
}
+ kv_info->scope = current_parsing_scope;
si->util = kv_info;
return 0;
@@ -2482,3 +2497,11 @@ const char *current_config_name(void)
die("BUG: current_config_name called outside config callback");
return name ? name : "";
}
+
+enum config_scope current_config_scope(void)
+{
+ if (current_config_kvi)
+ return current_config_kvi->scope;
+ else
+ return current_parsing_scope;
+}
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index 3605ef8ee6..509aeef400 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -35,6 +35,21 @@
*
*/
+static const char *scope_name(enum config_scope scope)
+{
+ switch (scope) {
+ case CONFIG_SCOPE_SYSTEM:
+ return "system";
+ case CONFIG_SCOPE_GLOBAL:
+ return "global";
+ case CONFIG_SCOPE_REPO:
+ return "repo";
+ case CONFIG_SCOPE_CMDLINE:
+ return "cmdline";
+ default:
+ return "unknown";
+ }
+}
static int iterate_cb(const char *var, const char *value, void *data)
{
static int nr;
@@ -46,6 +61,7 @@ static int iterate_cb(const char *var, const char *value, void *data)
printf("value=%s\n", value ? value : "(null)");
printf("origin=%s\n", current_config_origin_type());
printf("name=%s\n", current_config_name());
+ printf("scope=%s\n", scope_name(current_config_scope()));
return 0;
}
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index d345a885a3..065d5ebb09 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -238,16 +238,19 @@ test_expect_success 'iteration shows correct origins' '
value=from-home
origin=file
name=$(pwd)/.gitconfig
+ scope=global
key=foo.bar
value=from-repo
origin=file
name=.git/config
+ scope=repo
key=foo.bar
value=from-cmdline
origin=command line
name=
+ scope=cmdline
EOF
GIT_CONFIG_PARAMETERS=$cmdline_config test-config iterate >actual &&
test_cmp expect actual