All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Glen Choo via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Jonathan Tan" <jonathantanmy@google.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Emily Shaffer" <nasamuffin@google.com>,
	"Glen Choo" <chooglen@google.com>,
	"Glen Choo" <chooglen@google.com>
Subject: [PATCH v2 11/14] config: pass kvi to die_bad_number()
Date: Tue, 30 May 2023 18:42:09 +0000	[thread overview]
Message-ID: <504eb206b5a1ac12676752d68b2e2569dc6737ef.1685472134.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1497.v2.git.git.1685472132.gitgitgadget@gmail.com>

From: Glen Choo <chooglen@google.com>

Plumb "struct key_value_info" through all code paths that end in
die_bad_number(), which lets us remove the helper functions that read
analogous values from "struct config_reader". As a result, nothing reads
config_reader.config_kvi any more, so remove that too.

In config.c, this requires changing the signature of
git_configset_get_value() to 'return' "kvi" in an out parameter so that
git_configset_get_<type>() can pass it to git_config_<type>().

Outside of config.c, config callbacks now need to pass "kvi" to any of
the git_config_<type>() functions that parse a config string into a
number type. Included is a .cocci patch to make that refactor. In cases
where "kvi" would never be used, pass NULL, e.g.:

- In config.c, when we are parsing a boolean instead of a number
- In builtin/config.c, when calling normalize_value() before setting
  config to something the user gave us.

Signed-off-by: Glen Choo <chooglen@google.com>
---
 archive-tar.c                              |   4 +-
 builtin/commit-graph.c                     |   4 +-
 builtin/commit.c                           |  10 +-
 builtin/config.c                           |  20 +--
 builtin/fetch.c                            |   4 +-
 builtin/fsmonitor--daemon.c                |   6 +-
 builtin/grep.c                             |   2 +-
 builtin/index-pack.c                       |   4 +-
 builtin/log.c                              |   2 +-
 builtin/pack-objects.c                     |  14 +-
 builtin/receive-pack.c                     |  10 +-
 builtin/submodule--helper.c                |   4 +-
 config.c                                   | 153 ++++++++-------------
 config.h                                   |  14 +-
 contrib/coccinelle/git_config_number.cocci |  27 ++++
 diff.c                                     |   9 +-
 fmt-merge-msg.c                            |   2 +-
 help.c                                     |   5 +-
 http.c                                     |  10 +-
 imap-send.c                                |   2 +-
 sequencer.c                                |  22 +--
 setup.c                                    |   2 +-
 submodule-config.c                         |  15 +-
 submodule-config.h                         |   3 +-
 t/helper/test-config.c                     |   6 +-
 upload-pack.c                              |  12 +-
 worktree.c                                 |   2 +-
 27 files changed, 182 insertions(+), 186 deletions(-)
 create mode 100644 contrib/coccinelle/git_config_number.cocci

diff --git a/archive-tar.c b/archive-tar.c
index dcfbce5225a..1cd6d72d21e 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -411,14 +411,14 @@ static int tar_filter_config(const char *var, const char *value,
 }
 
 static int git_tar_config(const char *var, const char *value,
-			  struct key_value_info *kvi UNUSED, void *cb)
+			  struct key_value_info *kvi, void *cb)
 {
 	if (!strcmp(var, "tar.umask")) {
 		if (value && !strcmp(value, "user")) {
 			tar_umask = umask(0);
 			umask(tar_umask);
 		} else {
-			tar_umask = git_config_int(var, value);
+			tar_umask = git_config_int(var, value, kvi);
 		}
 		return 0;
 	}
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index e811866b5dd..c99804abc7e 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -185,11 +185,11 @@ static int write_option_max_new_filters(const struct option *opt,
 }
 
 static int git_commit_graph_write_config(const char *var, const char *value,
-					 struct key_value_info *kvi UNUSED,
+					 struct key_value_info *kvi,
 					 void *cb UNUSED)
 {
 	if (!strcmp(var, "commitgraph.maxnewfilters"))
-		write_opts.max_new_filters = git_config_int(var, value);
+		write_opts.max_new_filters = git_config_int(var, value, kvi);
 	/*
 	 * No need to fall-back to 'git_default_config', since this was already
 	 * called in 'cmd_commit_graph()'.
diff --git a/builtin/commit.c b/builtin/commit.c
index ec468e87039..e846355ec39 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1412,7 +1412,8 @@ static int git_status_config(const char *k, const char *v,
 		return git_column_config(k, v, "status", &s->colopts);
 	if (!strcmp(k, "status.submodulesummary")) {
 		int is_bool;
-		s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
+		s->submodule_summary = git_config_bool_or_int(k, v, kvi,
+							      &is_bool);
 		if (is_bool && s->submodule_summary)
 			s->submodule_summary = -1;
 		return 0;
@@ -1472,11 +1473,11 @@ static int git_status_config(const char *k, const char *v,
 	}
 	if (!strcmp(k, "diff.renamelimit")) {
 		if (s->rename_limit == -1)
-			s->rename_limit = git_config_int(k, v);
+			s->rename_limit = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "status.renamelimit")) {
-		s->rename_limit = git_config_int(k, v);
+		s->rename_limit = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "diff.renames")) {
@@ -1622,7 +1623,8 @@ static int git_commit_config(const char *k, const char *v,
 	}
 	if (!strcmp(k, "commit.verbose")) {
 		int is_bool;
-		config_commit_verbose = git_config_bool_or_int(k, v, &is_bool);
+		config_commit_verbose = git_config_bool_or_int(k, v, kvi,
+							       &is_bool);
 		return 0;
 	}
 
diff --git a/builtin/config.c b/builtin/config.c
index 2fcad601a7b..0a33bea26c0 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -254,13 +254,14 @@ static int format_config(struct strbuf *buf, const char *key_,
 
 		if (type == TYPE_INT)
 			strbuf_addf(buf, "%"PRId64,
-				    git_config_int64(key_, value_ ? value_ : ""));
+				    git_config_int64(key_, value_ ? value_ : "", kvi));
 		else if (type == TYPE_BOOL)
 			strbuf_addstr(buf, git_config_bool(key_, value_) ?
 				      "true" : "false");
 		else if (type == TYPE_BOOL_OR_INT) {
 			int is_bool, v;
-			v = git_config_bool_or_int(key_, value_, &is_bool);
+			v = git_config_bool_or_int(key_, value_, kvi,
+						   &is_bool);
 			if (is_bool)
 				strbuf_addstr(buf, v ? "true" : "false");
 			else
@@ -414,7 +415,8 @@ free_strings:
 	return ret;
 }
 
-static char *normalize_value(const char *key, const char *value)
+static char *normalize_value(const char *key, const char *value,
+			     struct key_value_info *kvi)
 {
 	if (!value)
 		return NULL;
@@ -429,12 +431,12 @@ static char *normalize_value(const char *key, const char *value)
 		 */
 		return xstrdup(value);
 	if (type == TYPE_INT)
-		return xstrfmt("%"PRId64, git_config_int64(key, value));
+		return xstrfmt("%"PRId64, git_config_int64(key, value, kvi));
 	if (type == TYPE_BOOL)
 		return xstrdup(git_config_bool(key, value) ?  "true" : "false");
 	if (type == TYPE_BOOL_OR_INT) {
 		int is_bool, v;
-		v = git_config_bool_or_int(key, value, &is_bool);
+		v = git_config_bool_or_int(key, value, kvi, &is_bool);
 		if (!is_bool)
 			return xstrfmt("%d", v);
 		else
@@ -876,7 +878,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	else if (actions == ACTION_SET) {
 		check_write();
 		check_argc(argc, 2, 2);
-		value = normalize_value(argv[0], argv[1]);
+		value = normalize_value(argv[0], argv[1], NULL);
 		ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value);
 		if (ret == CONFIG_NOTHING_SET)
 			error(_("cannot overwrite multiple values with a single value\n"
@@ -885,7 +887,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	else if (actions == ACTION_SET_ALL) {
 		check_write();
 		check_argc(argc, 2, 3);
-		value = normalize_value(argv[0], argv[1]);
+		value = normalize_value(argv[0], argv[1], NULL);
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value, argv[2],
 							     flags);
@@ -893,7 +895,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	else if (actions == ACTION_ADD) {
 		check_write();
 		check_argc(argc, 2, 2);
-		value = normalize_value(argv[0], argv[1]);
+		value = normalize_value(argv[0], argv[1], NULL);
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value,
 							     CONFIG_REGEX_NONE,
@@ -902,7 +904,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	else if (actions == ACTION_REPLACE_ALL) {
 		check_write();
 		check_argc(argc, 2, 3);
-		value = normalize_value(argv[0], argv[1]);
+		value = normalize_value(argv[0], argv[1], NULL);
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value, argv[2],
 							     flags | CONFIG_FLAGS_MULTI_REPLACE);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index aa688291613..04cf5518d2c 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -125,7 +125,7 @@ static int git_fetch_config(const char *k, const char *v,
 	}
 
 	if (!strcmp(k, "submodule.fetchjobs")) {
-		submodule_fetch_jobs_config = parse_submodule_fetchjobs(k, v);
+		submodule_fetch_jobs_config = parse_submodule_fetchjobs(k, v, kvi);
 		return 0;
 	} else if (!strcmp(k, "fetch.recursesubmodules")) {
 		recurse_submodules = parse_fetch_recurse_submodules_arg(k, v);
@@ -133,7 +133,7 @@ static int git_fetch_config(const char *k, const char *v,
 	}
 
 	if (!strcmp(k, "fetch.parallel")) {
-		fetch_parallel_config = git_config_int(k, v);
+		fetch_parallel_config = git_config_int(k, v, kvi);
 		if (fetch_parallel_config < 0)
 			die(_("fetch.parallel cannot be negative"));
 		if (!fetch_parallel_config)
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index a7375d61d02..cde4a575836 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -40,7 +40,7 @@ static int fsmonitor_config(const char *var, const char *value,
 			    struct key_value_info *kvi, void *cb)
 {
 	if (!strcmp(var, FSMONITOR__IPC_THREADS)) {
-		int i = git_config_int(var, value);
+		int i = git_config_int(var, value, kvi);
 		if (i < 1)
 			return error(_("value of '%s' out of range: %d"),
 				     FSMONITOR__IPC_THREADS, i);
@@ -49,7 +49,7 @@ static int fsmonitor_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, FSMONITOR__START_TIMEOUT)) {
-		int i = git_config_int(var, value);
+		int i = git_config_int(var, value, kvi);
 		if (i < 0)
 			return error(_("value of '%s' out of range: %d"),
 				     FSMONITOR__START_TIMEOUT, i);
@@ -59,7 +59,7 @@ static int fsmonitor_config(const char *var, const char *value,
 
 	if (!strcmp(var, FSMONITOR__ANNOUNCE_STARTUP)) {
 		int is_bool;
-		int i = git_config_bool_or_int(var, value, &is_bool);
+		int i = git_config_bool_or_int(var, value, kvi, &is_bool);
 		if (i < 0)
 			return error(_("value of '%s' not bool or int: %d"),
 				     var, i);
diff --git a/builtin/grep.c b/builtin/grep.c
index 6e795f9f3a2..edb57f048ef 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -298,7 +298,7 @@ static int grep_cmd_config(const char *var, const char *value,
 		st = -1;
 
 	if (!strcmp(var, "grep.threads")) {
-		num_threads = git_config_int(var, value);
+		num_threads = git_config_int(var, value, kvi);
 		if (num_threads < 0)
 			die(_("invalid number of threads specified (%d) for %s"),
 			    num_threads, var);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 4450510ddfc..e7685fa9a6f 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1584,13 +1584,13 @@ static int git_index_pack_config(const char *k, const char *v,
 	struct pack_idx_option *opts = cb;
 
 	if (!strcmp(k, "pack.indexversion")) {
-		opts->version = git_config_int(k, v);
+		opts->version = git_config_int(k, v, kvi);
 		if (opts->version > 2)
 			die(_("bad pack.indexVersion=%"PRIu32), opts->version);
 		return 0;
 	}
 	if (!strcmp(k, "pack.threads")) {
-		nr_threads = git_config_int(k, v);
+		nr_threads = git_config_int(k, v, kvi);
 		if (nr_threads < 0)
 			die(_("invalid number of threads specified (%d)"),
 			    nr_threads);
diff --git a/builtin/log.c b/builtin/log.c
index f8e61330491..805320a1abf 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -569,7 +569,7 @@ static int git_log_config(const char *var, const char *value,
 	if (!strcmp(var, "format.subjectprefix"))
 		return git_config_string(&fmt_patch_subject_prefix, var, value);
 	if (!strcmp(var, "format.filenamemaxlength")) {
-		fmt_patch_name_max = git_config_int(var, value);
+		fmt_patch_name_max = git_config_int(var, value, kvi);
 		return 0;
 	}
 	if (!strcmp(var, "format.encodeemailheaders")) {
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index ca023000cc0..cde11f83f81 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3138,23 +3138,23 @@ static int git_pack_config(const char *k, const char *v,
 			   struct key_value_info *kvi, void *cb)
 {
 	if (!strcmp(k, "pack.window")) {
-		window = git_config_int(k, v);
+		window = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "pack.windowmemory")) {
-		window_memory_limit = git_config_ulong(k, v);
+		window_memory_limit = git_config_ulong(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "pack.depth")) {
-		depth = git_config_int(k, v);
+		depth = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "pack.deltacachesize")) {
-		max_delta_cache_size = git_config_int(k, v);
+		max_delta_cache_size = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "pack.deltacachelimit")) {
-		cache_max_small_delta_size = git_config_int(k, v);
+		cache_max_small_delta_size = git_config_int(k, v, kvi);
 		return 0;
 	}
 	if (!strcmp(k, "pack.writebitmaphashcache")) {
@@ -3180,7 +3180,7 @@ static int git_pack_config(const char *k, const char *v,
 		return 0;
 	}
 	if (!strcmp(k, "pack.threads")) {
-		delta_search_threads = git_config_int(k, v);
+		delta_search_threads = git_config_int(k, v, kvi);
 		if (delta_search_threads < 0)
 			die(_("invalid number of threads specified (%d)"),
 			    delta_search_threads);
@@ -3191,7 +3191,7 @@ static int git_pack_config(const char *k, const char *v,
 		return 0;
 	}
 	if (!strcmp(k, "pack.indexversion")) {
-		pack_idx_opts.version = git_config_int(k, v);
+		pack_idx_opts.version = git_config_int(k, v, kvi);
 		if (pack_idx_opts.version > 2)
 			die(_("bad pack.indexVersion=%"PRIu32),
 			    pack_idx_opts.version);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 2f5fd2abbc3..d2bc0fead9f 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -154,12 +154,12 @@ static int receive_pack_config(const char *var, const char *value,
 	}
 
 	if (strcmp(var, "receive.unpacklimit") == 0) {
-		receive_unpack_limit = git_config_int(var, value);
+		receive_unpack_limit = git_config_int(var, value, kvi);
 		return 0;
 	}
 
 	if (strcmp(var, "transfer.unpacklimit") == 0) {
-		transfer_unpack_limit = git_config_int(var, value);
+		transfer_unpack_limit = git_config_int(var, value, kvi);
 		return 0;
 	}
 
@@ -227,7 +227,7 @@ static int receive_pack_config(const char *var, const char *value,
 		return git_config_string(&cert_nonce_seed, var, value);
 
 	if (strcmp(var, "receive.certnonceslop") == 0) {
-		nonce_stamp_slop_limit = git_config_ulong(var, value);
+		nonce_stamp_slop_limit = git_config_ulong(var, value, kvi);
 		return 0;
 	}
 
@@ -242,12 +242,12 @@ static int receive_pack_config(const char *var, const char *value,
 	}
 
 	if (strcmp(var, "receive.keepalive") == 0) {
-		keepalive_in_sec = git_config_int(var, value);
+		keepalive_in_sec = git_config_int(var, value, kvi);
 		return 0;
 	}
 
 	if (strcmp(var, "receive.maxinputsize") == 0) {
-		max_input_size = git_config_int64(var, value);
+		max_input_size = git_config_int64(var, value, kvi);
 		return 0;
 	}
 
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 8570effbf0d..bda10764db5 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2187,13 +2187,13 @@ static int update_clone_task_finished(int result,
 }
 
 static int git_update_clone_config(const char *var, const char *value,
-				   struct key_value_info *kvi UNUSED,
+				   struct key_value_info *kvi,
 				   void *cb)
 {
 	int *max_jobs = cb;
 
 	if (!strcmp(var, "submodule.fetchjobs"))
-		*max_jobs = parse_submodule_fetchjobs(var, value);
+		*max_jobs = parse_submodule_fetchjobs(var, value, kvi);
 	return 0;
 }
 
diff --git a/config.c b/config.c
index 819e9e5966c..34a111b2e1c 100644
--- a/config.c
+++ b/config.c
@@ -66,18 +66,8 @@ struct config_reader {
 	 *
 	 * The "source" variable will be non-NULL only when we are actually
 	 * parsing a real config source (file, blob, cmdline, etc).
-	 *
-	 * The "config_kvi" variable will be non-NULL only when we are feeding
-	 * cached config from a configset into a callback.
-	 *
-	 * They cannot be non-NULL at the same time. If they are both NULL, then
-	 * we aren't parsing anything (and depending on the function looking at
-	 * the variables, it's either a bug for it to be called in the first
-	 * place, or it's a function which can be reused for non-config
-	 * purposes, and should fall back to some sane behavior).
 	 */
 	struct config_source *source;
-	struct key_value_info *config_kvi;
 };
 /*
  * Where possible, prefer to accept "struct config_reader" as an arg than to use
@@ -89,8 +79,6 @@ static struct config_reader the_reader;
 static inline void config_reader_push_source(struct config_reader *reader,
 					     struct config_source *top)
 {
-	if (reader->config_kvi)
-		BUG("source should not be set while iterating a config set");
 	top->prev = reader->source;
 	reader->source = top;
 }
@@ -105,12 +93,6 @@ static inline struct config_source *config_reader_pop_source(struct config_reade
 	return ret;
 }
 
-static inline void config_reader_set_kvi(struct config_reader *reader,
-					 struct key_value_info *kvi)
-{
-	reader->config_kvi = kvi;
-}
-
 static int pack_compression_seen;
 static int zlib_compression_seen;
 
@@ -1330,80 +1312,74 @@ int git_parse_ssize_t(const char *value, ssize_t *ret)
 	return 1;
 }
 
-static int reader_config_name(struct config_reader *reader, const char **out);
-static int reader_origin_type(struct config_reader *reader,
-			      enum config_origin_type *type);
 NORETURN
-static void die_bad_number(struct config_reader *reader, const char *name,
-			   const char *value)
+static void die_bad_number(const char *name, const char *value,
+			   struct key_value_info *kvi)
 {
 	const char *error_type = (errno == ERANGE) ?
 		N_("out of range") : N_("invalid unit");
 	const char *bad_numeric = N_("bad numeric config value '%s' for '%s': %s");
-	const char *config_name = NULL;
-	enum config_origin_type config_origin = CONFIG_ORIGIN_UNKNOWN;
 
 	if (!value)
 		value = "";
 
-	/* Ignoring the return value is okay since we handle missing values. */
-	reader_config_name(reader, &config_name);
-	reader_origin_type(reader, &config_origin);
-
-	if (!config_name)
+	if (!kvi || !kvi->filename)
 		die(_(bad_numeric), value, name, _(error_type));
 
-	switch (config_origin) {
+	switch (kvi->origin_type) {
 	case CONFIG_ORIGIN_BLOB:
 		die(_("bad numeric config value '%s' for '%s' in blob %s: %s"),
-		    value, name, config_name, _(error_type));
+		    value, name, kvi->filename, _(error_type));
 	case CONFIG_ORIGIN_FILE:
 		die(_("bad numeric config value '%s' for '%s' in file %s: %s"),
-		    value, name, config_name, _(error_type));
+		    value, name, kvi->filename, _(error_type));
 	case CONFIG_ORIGIN_STDIN:
 		die(_("bad numeric config value '%s' for '%s' in standard input: %s"),
 		    value, name, _(error_type));
 	case CONFIG_ORIGIN_SUBMODULE_BLOB:
 		die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"),
-		    value, name, config_name, _(error_type));
+		    value, name, kvi->filename, _(error_type));
 	case CONFIG_ORIGIN_CMDLINE:
 		die(_("bad numeric config value '%s' for '%s' in command line %s: %s"),
-		    value, name, config_name, _(error_type));
+		    value, name, kvi->filename, _(error_type));
 	default:
 		die(_("bad numeric config value '%s' for '%s' in %s: %s"),
-		    value, name, config_name, _(error_type));
+		    value, name, kvi->filename, _(error_type));
 	}
 }
 
-int git_config_int(const char *name, const char *value)
+int git_config_int(const char *name, const char *value,
+		   struct key_value_info *kvi)
 {
 	int ret;
 	if (!git_parse_int(value, &ret))
-		die_bad_number(&the_reader, name, value);
+		die_bad_number(name, value, kvi);
 	return ret;
 }
 
-int64_t git_config_int64(const char *name, const char *value)
+int64_t git_config_int64(const char *name, const char *value, struct key_value_info *kvi)
 {
 	int64_t ret;
 	if (!git_parse_int64(value, &ret))
-		die_bad_number(&the_reader, name, value);
+		die_bad_number(name, value, kvi);
 	return ret;
 }
 
-unsigned long git_config_ulong(const char *name, const char *value)
+unsigned long git_config_ulong(const char *name, const char *value,
+			       struct key_value_info *kvi)
 {
 	unsigned long ret;
 	if (!git_parse_ulong(value, &ret))
-		die_bad_number(&the_reader, name, value);
+		die_bad_number(name, value, kvi);
 	return ret;
 }
 
-ssize_t git_config_ssize_t(const char *name, const char *value)
+ssize_t git_config_ssize_t(const char *name, const char *value,
+			   struct key_value_info *kvi)
 {
 	ssize_t ret;
 	if (!git_parse_ssize_t(value, &ret))
-		die_bad_number(&the_reader, name, value);
+		die_bad_number(name, value, kvi);
 	return ret;
 }
 
@@ -1508,7 +1484,8 @@ int git_parse_maybe_bool(const char *value)
 	return -1;
 }
 
-int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
+int git_config_bool_or_int(const char *name, const char *value,
+			   struct key_value_info *kvi, int *is_bool)
 {
 	int v = git_parse_maybe_bool_text(value);
 	if (0 <= v) {
@@ -1516,7 +1493,7 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
 		return v;
 	}
 	*is_bool = 0;
-	return git_config_int(name, value);
+	return git_config_int(name, value, kvi);
 }
 
 int git_config_bool(const char *name, const char *value)
@@ -1642,7 +1619,7 @@ static int git_default_core_config(const char *var, const char *value,
 		else if (!git_parse_maybe_bool_text(value))
 			default_abbrev = the_hash_algo->hexsz;
 		else {
-			int abbrev = git_config_int(var, value);
+			int abbrev = git_config_int(var, value, kvi);
 			if (abbrev < minimum_abbrev || abbrev > the_hash_algo->hexsz)
 				return error(_("abbrev length out of range: %d"), abbrev);
 			default_abbrev = abbrev;
@@ -1654,7 +1631,7 @@ static int git_default_core_config(const char *var, const char *value,
 		return set_disambiguate_hint_config(var, value);
 
 	if (!strcmp(var, "core.loosecompression")) {
-		int level = git_config_int(var, value);
+		int level = git_config_int(var, value, kvi);
 		if (level == -1)
 			level = Z_DEFAULT_COMPRESSION;
 		else if (level < 0 || level > Z_BEST_COMPRESSION)
@@ -1665,7 +1642,7 @@ static int git_default_core_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, "core.compression")) {
-		int level = git_config_int(var, value);
+		int level = git_config_int(var, value, kvi);
 		if (level == -1)
 			level = Z_DEFAULT_COMPRESSION;
 		else if (level < 0 || level > Z_BEST_COMPRESSION)
@@ -1679,7 +1656,7 @@ static int git_default_core_config(const char *var, const char *value,
 
 	if (!strcmp(var, "core.packedgitwindowsize")) {
 		int pgsz_x2 = getpagesize() * 2;
-		packed_git_window_size = git_config_ulong(var, value);
+		packed_git_window_size = git_config_ulong(var, value, kvi);
 
 		/* This value must be multiple of (pagesize * 2) */
 		packed_git_window_size /= pgsz_x2;
@@ -1690,17 +1667,17 @@ static int git_default_core_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, "core.bigfilethreshold")) {
-		big_file_threshold = git_config_ulong(var, value);
+		big_file_threshold = git_config_ulong(var, value, kvi);
 		return 0;
 	}
 
 	if (!strcmp(var, "core.packedgitlimit")) {
-		packed_git_limit = git_config_ulong(var, value);
+		packed_git_limit = git_config_ulong(var, value, kvi);
 		return 0;
 	}
 
 	if (!strcmp(var, "core.deltabasecachelimit")) {
-		delta_base_cache_limit = git_config_ulong(var, value);
+		delta_base_cache_limit = git_config_ulong(var, value, kvi);
 		return 0;
 	}
 
@@ -1984,12 +1961,12 @@ int git_default_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, "pack.packsizelimit")) {
-		pack_size_limit_cfg = git_config_ulong(var, value);
+		pack_size_limit_cfg = git_config_ulong(var, value, kvi);
 		return 0;
 	}
 
 	if (!strcmp(var, "pack.compression")) {
-		int level = git_config_int(var, value);
+		int level = git_config_int(var, value, kvi);
 		if (level == -1)
 			level = Z_DEFAULT_COMPRESSION;
 		else if (level < 0 || level > Z_BEST_COMPRESSION)
@@ -2323,11 +2300,8 @@ static void configset_iter(struct config_reader *reader, struct config_set *set,
 		values = &entry->value_list;
 		kvi = values->items[value_index].util;
 
-		config_reader_set_kvi(reader, values->items[value_index].util);
-
 		if (fn(entry->key, values->items[value_index].string, kvi, data) < 0)
 			git_die_config_linenr(entry->key, kvi->filename, kvi->linenr);
-		config_reader_set_kvi(reader, NULL);
 	}
 }
 
@@ -2509,11 +2483,12 @@ int git_configset_add_file(struct config_set *set, const char *filename)
 	return git_config_from_file(config_set_callback, filename, &data);
 }
 
-int git_configset_get_value(struct config_set *set, const char *key, const char **value)
+int git_configset_get_value(struct config_set *set, const char *key,
+			    const char **value, struct key_value_info *kvi)
 {
 	const struct string_list *values = NULL;
 	int ret;
-
+	struct string_list_item item;
 	/*
 	 * Follows "last one wins" semantic, i.e., if there are multiple matches for the
 	 * queried key in the files of the configset, the value returned will be the last
@@ -2523,7 +2498,10 @@ int git_configset_get_value(struct config_set *set, const char *key, const char
 		return ret;
 
 	assert(values->nr > 0);
-	*value = values->items[values->nr - 1].string;
+	item = values->items[values->nr - 1];
+	*value = item.string;
+	if (kvi)
+		*kvi = *((struct key_value_info *)item.util);
 	return 0;
 }
 
@@ -2576,7 +2554,7 @@ int git_configset_get(struct config_set *set, const char *key)
 int git_configset_get_string(struct config_set *set, const char *key, char **dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value))
+	if (!git_configset_get_value(set, key, &value, NULL))
 		return git_config_string((const char **)dest, key, value);
 	else
 		return 1;
@@ -2586,7 +2564,7 @@ static int git_configset_get_string_tmp(struct config_set *set, const char *key,
 					const char **dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
+	if (!git_configset_get_value(set, key, &value, NULL)) {
 		if (!value)
 			return config_error_nonbool(key);
 		*dest = value;
@@ -2599,8 +2577,10 @@ static int git_configset_get_string_tmp(struct config_set *set, const char *key,
 int git_configset_get_int(struct config_set *set, const char *key, int *dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
-		*dest = git_config_int(key, value);
+	struct key_value_info kvi;
+
+	if (!git_configset_get_value(set, key, &value, &kvi)) {
+		*dest = git_config_int(key, value, &kvi);
 		return 0;
 	} else
 		return 1;
@@ -2609,8 +2589,10 @@ int git_configset_get_int(struct config_set *set, const char *key, int *dest)
 int git_configset_get_ulong(struct config_set *set, const char *key, unsigned long *dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
-		*dest = git_config_ulong(key, value);
+	struct key_value_info kvi;
+
+	if (!git_configset_get_value(set, key, &value, &kvi)) {
+		*dest = git_config_ulong(key, value, &kvi);
 		return 0;
 	} else
 		return 1;
@@ -2619,7 +2601,7 @@ int git_configset_get_ulong(struct config_set *set, const char *key, unsigned lo
 int git_configset_get_bool(struct config_set *set, const char *key, int *dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
+	if (!git_configset_get_value(set, key, &value, NULL)) {
 		*dest = git_config_bool(key, value);
 		return 0;
 	} else
@@ -2630,8 +2612,10 @@ int git_configset_get_bool_or_int(struct config_set *set, const char *key,
 				int *is_bool, int *dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
-		*dest = git_config_bool_or_int(key, value, is_bool);
+	struct key_value_info kvi;
+
+	if (!git_configset_get_value(set, key, &value, &kvi)) {
+		*dest = git_config_bool_or_int(key, value, &kvi, is_bool);
 		return 0;
 	} else
 		return 1;
@@ -2640,7 +2624,7 @@ int git_configset_get_bool_or_int(struct config_set *set, const char *key,
 int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value)) {
+	if (!git_configset_get_value(set, key, &value, NULL)) {
 		*dest = git_parse_maybe_bool(value);
 		if (*dest == -1)
 			return -1;
@@ -2652,7 +2636,7 @@ int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *d
 int git_configset_get_pathname(struct config_set *set, const char *key, const char **dest)
 {
 	const char *value;
-	if (!git_configset_get_value(set, key, &value))
+	if (!git_configset_get_value(set, key, &value, NULL))
 		return git_config_pathname(dest, key, value);
 	else
 		return 1;
@@ -2722,7 +2706,7 @@ int repo_config_get_value(struct repository *repo,
 			  const char *key, const char **value)
 {
 	git_config_check_init(repo);
-	return git_configset_get_value(repo->config, key, value);
+	return git_configset_get_value(repo->config, key, value, NULL);
 }
 
 int repo_config_get_value_multi(struct repository *repo, const char *key,
@@ -3946,18 +3930,6 @@ int parse_config_key(const char *var,
 	return 0;
 }
 
-static int reader_origin_type(struct config_reader *reader,
-			      enum config_origin_type *type)
-{
-	if (the_reader.config_kvi)
-		*type = reader->config_kvi->origin_type;
-	else if(the_reader.source)
-		*type = reader->source->origin_type;
-	else
-		return 1;
-	return 0;
-}
-
 const char *config_origin_type_name(enum config_origin_type type)
 {
 	switch (type) {
@@ -3996,17 +3968,6 @@ const char *config_scope_name(enum config_scope scope)
 	}
 }
 
-static int reader_config_name(struct config_reader *reader, const char **out)
-{
-	if (the_reader.config_kvi)
-		*out = reader->config_kvi->filename;
-	else if (the_reader.source)
-		*out = reader->source->name;
-	else
-		return 1;
-	return 0;
-}
-
 int lookup_config(const char **mapping, int nr_mapping, const char *var)
 {
 	int i;
diff --git a/config.h b/config.h
index 9e3c2bdb429..0fe56a4d650 100644
--- a/config.h
+++ b/config.h
@@ -229,22 +229,23 @@ int git_parse_maybe_bool(const char *);
  * Parse the string to an integer, including unit factors. Dies on error;
  * otherwise, returns the parsed result.
  */
-int git_config_int(const char *, const char *);
+int git_config_int(const char *, const char *, struct key_value_info *);
 
-int64_t git_config_int64(const char *, const char *);
+int64_t git_config_int64(const char *, const char *, struct key_value_info *);
 
 /**
  * Identical to `git_config_int`, but for unsigned longs.
  */
-unsigned long git_config_ulong(const char *, const char *);
+unsigned long git_config_ulong(const char *, const char *, struct key_value_info *);
 
-ssize_t git_config_ssize_t(const char *, const char *);
+ssize_t git_config_ssize_t(const char *, const char *, struct key_value_info *);
 
 /**
  * Same as `git_config_bool`, except that integers are returned as-is, and
  * an `is_bool` flag is unset.
  */
-int git_config_bool_or_int(const char *, const char *, int *);
+int git_config_bool_or_int(const char *, const char *, struct key_value_info *,
+			   int *);
 
 /**
  * Parse a string into a boolean value, respecting keywords like "true" and
@@ -509,7 +510,8 @@ int git_configset_get(struct config_set *cs, const char *key);
  * touching `value`. The caller should not free or modify `value`, as it
  * is owned by the cache.
  */
-int git_configset_get_value(struct config_set *cs, const char *key, const char **dest);
+int git_configset_get_value(struct config_set *cs, const char *key,
+			    const char **dest, struct key_value_info *kvi);
 
 int git_configset_get_string(struct config_set *cs, const char *key, char **dest);
 int git_configset_get_int(struct config_set *cs, const char *key, int *dest);
diff --git a/contrib/coccinelle/git_config_number.cocci b/contrib/coccinelle/git_config_number.cocci
new file mode 100644
index 00000000000..f46c74dd23c
--- /dev/null
+++ b/contrib/coccinelle/git_config_number.cocci
@@ -0,0 +1,27 @@
+@@
+identifier C1, C2, C3;
+@@
+(
+(
+git_config_int
+|
+git_config_int64
+|
+git_config_ulong
+|
+git_config_ssize_t
+)
+  (C1, C2
++ , kvi
+  )
+|
+(
+git_configset_get_value
+|
+git_config_bool_or_int
+)
+  (C1, C2,
++ kvi,
+  C3
+  )
+)
diff --git a/diff.c b/diff.c
index d7ed2dc900b..da7cd353a6d 100644
--- a/diff.c
+++ b/diff.c
@@ -372,13 +372,14 @@ int git_diff_ui_config(const char *var, const char *value,
 		return 0;
 	}
 	if (!strcmp(var, "diff.context")) {
-		diff_context_default = git_config_int(var, value);
+		diff_context_default = git_config_int(var, value, kvi);
 		if (diff_context_default < 0)
 			return -1;
 		return 0;
 	}
 	if (!strcmp(var, "diff.interhunkcontext")) {
-		diff_interhunk_context_default = git_config_int(var, value);
+		diff_interhunk_context_default = git_config_int(var, value,
+								kvi);
 		if (diff_interhunk_context_default < 0)
 			return -1;
 		return 0;
@@ -404,7 +405,7 @@ int git_diff_ui_config(const char *var, const char *value,
 		return 0;
 	}
 	if (!strcmp(var, "diff.statgraphwidth")) {
-		diff_stat_graph_width = git_config_int(var, value);
+		diff_stat_graph_width = git_config_int(var, value, kvi);
 		return 0;
 	}
 	if (!strcmp(var, "diff.external"))
@@ -443,7 +444,7 @@ int git_diff_basic_config(const char *var, const char *value,
 	const char *name;
 
 	if (!strcmp(var, "diff.renamelimit")) {
-		diff_rename_limit_default = git_config_int(var, value);
+		diff_rename_limit_default = git_config_int(var, value, kvi);
 		return 0;
 	}
 
diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 97358034fa0..d1b59af44bb 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -24,7 +24,7 @@ int fmt_merge_msg_config(const char *key, const char *value,
 {
 	if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) {
 		int is_bool;
-		merge_log_config = git_config_bool_or_int(key, value, &is_bool);
+		merge_log_config = git_config_bool_or_int(key, value, kvi, &is_bool);
 		if (!is_bool && merge_log_config < 0)
 			return error("%s: negative length %s", key, value);
 		if (is_bool && merge_log_config)
diff --git a/help.c b/help.c
index 43d1eb702cd..08f0b953736 100644
--- a/help.c
+++ b/help.c
@@ -545,8 +545,7 @@ static struct cmdnames aliases;
 #define AUTOCORRECT_IMMEDIATELY (-1)
 
 static int git_unknown_cmd_config(const char *var, const char *value,
-				  struct key_value_info *kvi UNUSED,
-				  void *cb UNUSED)
+				  struct key_value_info *kvi, void *cb UNUSED)
 {
 	const char *p;
 
@@ -560,7 +559,7 @@ static int git_unknown_cmd_config(const char *var, const char *value,
 		} else if (!strcmp(value, "prompt")) {
 			autocorrect = AUTOCORRECT_PROMPT;
 		} else {
-			int v = git_config_int(var, value);
+			int v = git_config_int(var, value, kvi);
 			autocorrect = (v < 0)
 				? AUTOCORRECT_IMMEDIATELY : v;
 		}
diff --git a/http.c b/http.c
index 3d4292eba6a..a26c3dff827 100644
--- a/http.c
+++ b/http.c
@@ -412,21 +412,21 @@ static int http_options(const char *var, const char *value,
 	}
 
 	if (!strcmp("http.minsessions", var)) {
-		min_curl_sessions = git_config_int(var, value);
+		min_curl_sessions = git_config_int(var, value, kvi);
 		if (min_curl_sessions > 1)
 			min_curl_sessions = 1;
 		return 0;
 	}
 	if (!strcmp("http.maxrequests", var)) {
-		max_requests = git_config_int(var, value);
+		max_requests = git_config_int(var, value, kvi);
 		return 0;
 	}
 	if (!strcmp("http.lowspeedlimit", var)) {
-		curl_low_speed_limit = (long)git_config_int(var, value);
+		curl_low_speed_limit = (long)git_config_int(var, value, kvi);
 		return 0;
 	}
 	if (!strcmp("http.lowspeedtime", var)) {
-		curl_low_speed_time = (long)git_config_int(var, value);
+		curl_low_speed_time = (long)git_config_int(var, value, kvi);
 		return 0;
 	}
 
@@ -462,7 +462,7 @@ static int http_options(const char *var, const char *value,
 	}
 
 	if (!strcmp("http.postbuffer", var)) {
-		http_post_buffer = git_config_ssize_t(var, value);
+		http_post_buffer = git_config_ssize_t(var, value, kvi);
 		if (http_post_buffer < 0)
 			warning(_("negative value for http.postBuffer; defaulting to %d"), LARGE_PACKET_MAX);
 		if (http_post_buffer < LARGE_PACKET_MAX)
diff --git a/imap-send.c b/imap-send.c
index 3cc98f1a0a5..3c391a52c5a 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1341,7 +1341,7 @@ static int git_imap_config(const char *var, const char *val,
 	else if (!strcmp("imap.authmethod", var))
 		return git_config_string(&server.auth_method, var, val);
 	else if (!strcmp("imap.port", var))
-		server.port = git_config_int(var, val);
+		server.port = git_config_int(var, val, kvi);
 	else if (!strcmp("imap.host", var)) {
 		if (!val) {
 			git_die_config("imap.host", "Missing value for 'imap.host'");
diff --git a/sequencer.c b/sequencer.c
index 171561c2cdb..76b4750b4bd 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2878,7 +2878,7 @@ static int git_config_string_dup(char **dest,
 }
 
 static int populate_opts_cb(const char *key, const char *value,
-			    struct key_value_info *kvi UNUSED, void *data)
+			    struct key_value_info *kvi, void *data)
 {
 	struct replay_opts *opts = data;
 	int error_flag = 1;
@@ -2886,26 +2886,26 @@ static int populate_opts_cb(const char *key, const char *value,
 	if (!value)
 		error_flag = 0;
 	else if (!strcmp(key, "options.no-commit"))
-		opts->no_commit = git_config_bool_or_int(key, value, &error_flag);
+		opts->no_commit = git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.edit"))
-		opts->edit = git_config_bool_or_int(key, value, &error_flag);
+		opts->edit = git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.allow-empty"))
 		opts->allow_empty =
-			git_config_bool_or_int(key, value, &error_flag);
+			git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.allow-empty-message"))
 		opts->allow_empty_message =
-			git_config_bool_or_int(key, value, &error_flag);
+			git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.keep-redundant-commits"))
 		opts->keep_redundant_commits =
-			git_config_bool_or_int(key, value, &error_flag);
+			git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.signoff"))
-		opts->signoff = git_config_bool_or_int(key, value, &error_flag);
+		opts->signoff = git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.record-origin"))
-		opts->record_origin = git_config_bool_or_int(key, value, &error_flag);
+		opts->record_origin = git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.allow-ff"))
-		opts->allow_ff = git_config_bool_or_int(key, value, &error_flag);
+		opts->allow_ff = git_config_bool_or_int(key, value, kvi, &error_flag);
 	else if (!strcmp(key, "options.mainline"))
-		opts->mainline = git_config_int(key, value);
+		opts->mainline = git_config_int(key, value, kvi);
 	else if (!strcmp(key, "options.strategy"))
 		git_config_string_dup(&opts->strategy, key, value);
 	else if (!strcmp(key, "options.gpg-sign"))
@@ -2915,7 +2915,7 @@ static int populate_opts_cb(const char *key, const char *value,
 		opts->xopts[opts->xopts_nr++] = xstrdup(value);
 	} else if (!strcmp(key, "options.allow-rerere-auto"))
 		opts->allow_rerere_auto =
-			git_config_bool_or_int(key, value, &error_flag) ?
+			git_config_bool_or_int(key, value, kvi, &error_flag) ?
 				RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE;
 	else if (!strcmp(key, "options.default-msg-cleanup")) {
 		opts->explicit_cleanup = 1;
diff --git a/setup.c b/setup.c
index a461dd15233..75934d7438f 100644
--- a/setup.c
+++ b/setup.c
@@ -594,7 +594,7 @@ static int check_repo_format(const char *var, const char *value,
 	const char *ext;
 
 	if (strcmp(var, "core.repositoryformatversion") == 0)
-		data->version = git_config_int(var, value);
+		data->version = git_config_int(var, value, kvi);
 	else if (skip_prefix(var, "extensions.", &ext)) {
 		switch (handle_extension_v0(var, value, ext, data)) {
 		case EXTENSION_ERROR:
diff --git a/submodule-config.c b/submodule-config.c
index 7d773f33621..b86547fd1ee 100644
--- a/submodule-config.c
+++ b/submodule-config.c
@@ -302,9 +302,10 @@ static int parse_fetch_recurse(const char *opt, const char *arg,
 	}
 }
 
-int parse_submodule_fetchjobs(const char *var, const char *value)
+int parse_submodule_fetchjobs(const char *var, const char *value,
+			      struct key_value_info *kvi)
 {
-	int fetchjobs = git_config_int(var, value);
+	int fetchjobs = git_config_int(var, value, kvi);
 	if (fetchjobs < 0)
 		die(_("negative values not allowed for submodule.fetchJobs"));
 	if (!fetchjobs)
@@ -848,14 +849,13 @@ struct fetch_config {
 };
 
 static int gitmodules_fetch_config(const char *var, const char *value,
-				   struct key_value_info *kvi UNUSED,
-				   void *cb)
+				   struct key_value_info *kvi, void *cb)
 {
 	struct fetch_config *config = cb;
 	if (!strcmp(var, "submodule.fetchjobs")) {
 		if (config->max_children)
 			*(config->max_children) =
-				parse_submodule_fetchjobs(var, value);
+				parse_submodule_fetchjobs(var, value, kvi);
 		return 0;
 	} else if (!strcmp(var, "fetch.recursesubmodules")) {
 		if (config->recurse_submodules)
@@ -877,12 +877,11 @@ void fetch_config_from_gitmodules(int *max_children, int *recurse_submodules)
 }
 
 static int gitmodules_update_clone_config(const char *var, const char *value,
-					  struct key_value_info *kvi UNUSED,
-					  void *cb)
+					  struct key_value_info *kvi, void *cb)
 {
 	int *max_jobs = cb;
 	if (!strcmp(var, "submodule.fetchjobs"))
-		*max_jobs = parse_submodule_fetchjobs(var, value);
+		*max_jobs = parse_submodule_fetchjobs(var, value, kvi);
 	return 0;
 }
 
diff --git a/submodule-config.h b/submodule-config.h
index c2045875bbb..944cae75cc9 100644
--- a/submodule-config.h
+++ b/submodule-config.h
@@ -50,7 +50,8 @@ struct repository;
 
 void submodule_cache_free(struct submodule_cache *cache);
 
-int parse_submodule_fetchjobs(const char *var, const char *value);
+int parse_submodule_fetchjobs(const char *var, const char *value,
+			      struct key_value_info *kvi);
 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
 struct option;
 int option_fetch_parse_recurse_submodules(const struct option *opt,
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index 7027ffa187f..737505583d4 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -61,12 +61,12 @@ static int iterate_cb(const char *var, const char *value,
 }
 
 static int parse_int_cb(const char *var, const char *value,
-			struct key_value_info *kvi UNUSED, void *data)
+			struct key_value_info *kvi, void *data)
 {
 	const char *key_to_match = data;
 
 	if (!strcmp(key_to_match, var)) {
-		int parsed = git_config_int(value, value);
+		int parsed = git_config_int(value, value, kvi);
 		printf("%d\n", parsed);
 	}
 	return 0;
@@ -179,7 +179,7 @@ int cmd__config(int argc, const char **argv)
 				goto exit2;
 			}
 		}
-		if (!git_configset_get_value(&cs, argv[2], &v)) {
+		if (!git_configset_get_value(&cs, argv[2], &v, NULL)) {
 			if (!v)
 				printf("(NULL)\n");
 			else
diff --git a/upload-pack.c b/upload-pack.c
index 5f8232ff078..7cf776cde91 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -1264,7 +1264,8 @@ static int find_symref(const char *refname,
 }
 
 static int parse_object_filter_config(const char *var, const char *value,
-				       struct upload_pack_data *data)
+				      struct key_value_info *kvi,
+				      struct upload_pack_data *data)
 {
 	struct strbuf buf = STRBUF_INIT;
 	const char *sub, *key;
@@ -1291,7 +1292,8 @@ static int parse_object_filter_config(const char *var, const char *value,
 		}
 		string_list_insert(&data->allowed_filters, buf.buf)->util =
 			(void *)(intptr_t)1;
-		data->tree_filter_max_depth = git_config_ulong(var, value);
+		data->tree_filter_max_depth = git_config_ulong(var, value,
+							       kvi);
 	}
 
 	strbuf_release(&buf);
@@ -1299,7 +1301,7 @@ static int parse_object_filter_config(const char *var, const char *value,
 }
 
 static int upload_pack_config(const char *var, const char *value,
-			      struct key_value_info *kvi UNUSED,
+			      struct key_value_info *kvi,
 			      void *cb_data)
 {
 	struct upload_pack_data *data = cb_data;
@@ -1320,7 +1322,7 @@ static int upload_pack_config(const char *var, const char *value,
 		else
 			data->allow_uor &= ~ALLOW_ANY_SHA1;
 	} else if (!strcmp("uploadpack.keepalive", var)) {
-		data->keepalive = git_config_int(var, value);
+		data->keepalive = git_config_int(var, value, kvi);
 		if (!data->keepalive)
 			data->keepalive = -1;
 	} else if (!strcmp("uploadpack.allowfilter", var)) {
@@ -1335,7 +1337,7 @@ static int upload_pack_config(const char *var, const char *value,
 		data->advertise_sid = git_config_bool(var, value);
 	}
 
-	if (parse_object_filter_config(var, value, data) < 0)
+	if (parse_object_filter_config(var, value, kvi, data) < 0)
 		return -1;
 
 	return parse_hide_refs_config(var, value, "uploadpack", &data->hidden_refs);
diff --git a/worktree.c b/worktree.c
index b5ee71c5ebd..1fbdbd745fb 100644
--- a/worktree.c
+++ b/worktree.c
@@ -835,7 +835,7 @@ int init_worktree_config(struct repository *r)
 	 * Relocate that value to avoid breaking all worktrees with this
 	 * upgrade to worktree config.
 	 */
-	if (!git_configset_get_value(&cs, "core.worktree", &core_worktree)) {
+	if (!git_configset_get_value(&cs, "core.worktree", &core_worktree, NULL)) {
 		if ((res = move_config_setting("core.worktree", core_worktree,
 					       common_config_file,
 					       main_worktree_file)))
-- 
gitgitgadget


  parent reply	other threads:[~2023-05-30 18:43 UTC|newest]

Thread overview: 115+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-21 19:13 [PATCH 00/14] [RFC] config: remove global state from config iteration Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 01/14] config.c: introduce kvi_fn(), use it for configsets Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 02/14] config.c: use kvi for CLI config Glen Choo via GitGitGadget
2023-05-01 11:06   ` Ævar Arnfjörð Bjarmason
2023-04-21 19:13 ` [PATCH 03/14] config: use kvi for config files Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 04/14] config: add kvi.path, use it to evaluate includes Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 05/14] config: pass source to config_parser_event_fn_t Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 06/14] config: inline git_color_default_config Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 07/14] urlmatch.h: use config_fn_t type Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 08/14] (RFC-only) config: add kvi arg to config_fn_t Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 09/14] (RFC-only) config: apply cocci to config_fn_t implementations Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 10/14] (RFC-only) config: finish config_fn_t refactor Glen Choo via GitGitGadget
2023-05-01 11:19   ` Ævar Arnfjörð Bjarmason
2023-05-05 21:07     ` Jonathan Tan
2023-05-09 22:46       ` Glen Choo
2023-05-11 16:21         ` Jonathan Tan
2023-05-08 21:00     ` Glen Choo
2023-04-21 19:13 ` [PATCH 11/14] config: remove current_config_(line|name|origin_type) Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 12/14] config: remove current_config_scope() Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 13/14] config: pass kvi to die_bad_number() Glen Choo via GitGitGadget
2023-04-21 19:13 ` [PATCH 14/14] config: remove config_reader from configset_add_value Glen Choo via GitGitGadget
2023-05-30 18:41 ` [PATCH v2 00/14] [RFC] config: remove global state from config iteration Glen Choo via GitGitGadget
2023-05-30 18:41   ` [PATCH v2 01/14] config: inline git_color_default_config Glen Choo via GitGitGadget
2023-05-30 18:42   ` [PATCH v2 02/14] urlmatch.h: use config_fn_t type Glen Choo via GitGitGadget
2023-05-30 18:42   ` [PATCH v2 03/14] (RFC-only) config: add kvi arg to config_fn_t Glen Choo via GitGitGadget
2023-06-01  9:50     ` Phillip Wood
2023-06-01 16:22       ` Glen Choo
2023-06-02  9:54         ` Phillip Wood
2023-06-02 16:46           ` Glen Choo
2023-06-05  9:38             ` Phillip Wood
2023-06-09 23:19               ` Glen Choo
2023-05-30 18:42   ` [PATCH v2 04/14] (RFC-only) config: apply cocci to config_fn_t implementations Glen Choo via GitGitGadget
2023-05-30 18:42   ` [PATCH v2 05/14] (RFC-only) config: finish config_fn_t refactor Glen Choo via GitGitGadget
2023-06-01 22:17     ` Jonathan Tan
2023-05-30 18:42   ` [PATCH v2 06/14] config.c: pass kvi in configsets Glen Choo via GitGitGadget
2023-06-01 22:21     ` Jonathan Tan
2023-05-30 18:42   ` [PATCH v2 07/14] config: provide kvi with config files Glen Choo via GitGitGadget
2023-06-01 22:41     ` Jonathan Tan
2023-06-01 23:54     ` Jonathan Tan
2023-05-30 18:42   ` [PATCH v2 08/14] builtin/config.c: test misuse of format_config() Glen Choo via GitGitGadget
2023-05-30 18:42   ` [PATCH v2 09/14] config.c: provide kvi with CLI config Glen Choo via GitGitGadget
2023-06-01 23:35     ` Jonathan Tan
2023-06-02 17:26       ` Glen Choo
2023-05-30 18:42   ` [PATCH v2 10/14] trace2: plumb config kvi Glen Choo via GitGitGadget
2023-06-01 23:38     ` Jonathan Tan
2023-05-30 18:42   ` Glen Choo via GitGitGadget [this message]
2023-06-01 23:48     ` [PATCH v2 11/14] config: pass kvi to die_bad_number() Jonathan Tan
2023-06-02 17:23       ` Glen Choo
2023-05-30 18:42   ` [PATCH v2 12/14] config.c: remove config_reader from configsets Glen Choo via GitGitGadget
2023-05-30 18:42   ` [PATCH v2 13/14] config: add kvi.path, use it to evaluate includes Glen Choo via GitGitGadget
2023-06-02  0:06     ` Jonathan Tan
2023-05-30 18:42   ` [PATCH v2 14/14] config: pass source to config_parser_event_fn_t Glen Choo via GitGitGadget
2023-06-02  0:08     ` Jonathan Tan
2023-06-02 17:20       ` Glen Choo
2023-06-20 19:43   ` [PATCH v3 00/12] config: remove global state from config iteration Glen Choo via GitGitGadget
2023-06-20 19:43     ` [PATCH v3 01/12] config: inline git_color_default_config Glen Choo via GitGitGadget
2023-06-20 21:01       ` Junio C Hamano
2023-06-20 19:43     ` [PATCH v3 02/12] urlmatch.h: use config_fn_t type Glen Choo via GitGitGadget
2023-06-20 21:02       ` Junio C Hamano
2023-06-20 19:43     ` [PATCH v3 03/12] config: add ctx arg to config_fn_t Glen Choo via GitGitGadget
2023-06-20 19:43     ` [PATCH v3 04/12] config.c: pass ctx in configsets Glen Choo via GitGitGadget
2023-06-20 21:19       ` Junio C Hamano
2023-06-20 19:43     ` [PATCH v3 05/12] config: pass ctx with config files Glen Choo via GitGitGadget
2023-06-20 19:43     ` [PATCH v3 06/12] builtin/config.c: test misuse of format_config() Glen Choo via GitGitGadget
2023-06-20 21:35       ` Junio C Hamano
2023-06-20 23:06         ` Glen Choo
2023-06-23 20:32       ` Jonathan Tan
2023-06-24  1:31         ` Jeff King
2023-06-28 17:28         ` Glen Choo
2023-06-20 19:43     ` [PATCH v3 07/12] config.c: pass ctx with CLI config Glen Choo via GitGitGadget
2023-06-23 20:35       ` Jonathan Tan
2023-06-23 21:41         ` Glen Choo
2023-06-20 19:43     ` [PATCH v3 08/12] trace2: plumb config kvi Glen Choo via GitGitGadget
2023-06-23 20:40       ` Jonathan Tan
2023-06-20 19:43     ` [PATCH v3 09/12] config: pass kvi to die_bad_number() Glen Choo via GitGitGadget
2023-06-20 19:43     ` [PATCH v3 10/12] config.c: remove config_reader from configsets Glen Choo via GitGitGadget
2023-06-23 20:57       ` Jonathan Tan
2023-06-23 21:33         ` Junio C Hamano
2023-06-20 19:43     ` [PATCH v3 11/12] config: add kvi.path, use it to evaluate includes Glen Choo via GitGitGadget
2023-06-20 19:43     ` [PATCH v3 12/12] config: pass source to config_parser_event_fn_t Glen Choo via GitGitGadget
2023-06-20 21:46       ` Junio C Hamano
2023-06-21 21:46     ` [PATCH v3 00/12] config: remove global state from config iteration Junio C Hamano
2023-06-21 23:06       ` Glen Choo
2023-06-23 21:02         ` Jonathan Tan
2023-06-23 21:33           ` Junio C Hamano
2023-06-23 21:45           ` Glen Choo
2023-06-26 18:11     ` [PATCH v4 " Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 01/12] config: inline git_color_default_config Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 02/12] urlmatch.h: use config_fn_t type Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 03/12] config: add ctx arg to config_fn_t Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 04/12] config.c: pass ctx in configsets Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 05/12] config: pass ctx with config files Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 06/12] builtin/config.c: test misuse of format_config() Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 07/12] config.c: pass ctx with CLI config Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 08/12] trace2: plumb config kvi Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 09/12] config: pass kvi to die_bad_number() Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 10/12] config.c: remove config_reader from configsets Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 11/12] config: add kvi.path, use it to evaluate includes Glen Choo via GitGitGadget
2023-06-26 18:11       ` [PATCH v4 12/12] config: pass source to config_parser_event_fn_t Glen Choo via GitGitGadget
2023-06-26 20:45       ` [PATCH v4 00/12] config: remove global state from config iteration Junio C Hamano
2023-06-28 19:26       ` [PATCH v5 00/11] " Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 01/11] config: inline git_color_default_config Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 02/11] urlmatch.h: use config_fn_t type Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 03/11] config: add ctx arg to config_fn_t Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 04/11] config.c: pass ctx in configsets Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 05/11] config: pass ctx with config files Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 06/11] config.c: pass ctx with CLI config Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 07/11] trace2: plumb config kvi Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 08/11] config: pass kvi to die_bad_number() Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 09/11] config.c: remove config_reader from configsets Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 10/11] config: add kvi.path, use it to evaluate includes Glen Choo via GitGitGadget
2023-06-28 19:26         ` [PATCH v5 11/11] config: pass source to config_parser_event_fn_t Glen Choo via GitGitGadget
2023-06-28 22:23         ` [PATCH v5 00/11] config: remove global state from config iteration Jonathan Tan
2023-06-28 22:47           ` Junio C Hamano
2023-07-11 18:41         ` Phillip Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=504eb206b5a1ac12676752d68b2e2569dc6737ef.1685472134.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=avarab@gmail.com \
    --cc=chooglen@google.com \
    --cc=git@vger.kernel.org \
    --cc=jonathantanmy@google.com \
    --cc=nasamuffin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.