Merge branch 'js/config-cb'

* js/config-cb:
  Provide git_config with a callback-data parameter

Conflicts:

	builtin-add.c
	builtin-cat-file.c
diff --git a/alias.c b/alias.c
index 116cac8..995f3e6 100644
--- a/alias.c
+++ b/alias.c
@@ -2,7 +2,8 @@
 
 static const char *alias_key;
 static char *alias_val;
-static int alias_lookup_cb(const char *k, const char *v)
+
+static int alias_lookup_cb(const char *k, const char *v, void *cb)
 {
 	if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) {
 		if (!v)
@@ -17,6 +18,6 @@
 {
 	alias_key = alias;
 	alias_val = NULL;
-	git_config(alias_lookup_cb);
+	git_config(alias_lookup_cb, NULL);
 	return alias_val;
 }
diff --git a/archive-tar.c b/archive-tar.c
index 4add802..d7598f9 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -220,7 +220,7 @@
 	strbuf_release(&ext_header);
 }
 
-static int git_tar_config(const char *var, const char *value)
+static int git_tar_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "tar.umask")) {
 		if (value && !strcmp(value, "user")) {
@@ -231,7 +231,7 @@
 		}
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int write_tar_entry(const unsigned char *sha1,
@@ -268,7 +268,7 @@
 {
 	int plen = args->base ? strlen(args->base) : 0;
 
-	git_config(git_tar_config);
+	git_config(git_tar_config, NULL);
 
 	archive_time = args->time;
 	verbose = args->verbose;
diff --git a/builtin-add.c b/builtin-add.c
index 6e4e645..1da22ee 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -207,13 +207,13 @@
 	OPT_END(),
 };
 
-static int add_config(const char *var, const char *value)
+static int add_config(const char *var, const char *value, void *cb)
 {
 	if (!strcasecmp(var, "add.ignore-errors")) {
 		ignore_add_errors = git_config_bool(var, value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 int cmd_add(int argc, const char **argv, const char *prefix)
@@ -231,7 +231,7 @@
 	if (add_interactive)
 		exit(interactive_add(argc, argv, prefix));
 
-	git_config(add_config);
+	git_config(add_config, NULL);
 
 	newfd = hold_locked_index(&lock_file, 1);
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 1540f28..c497889 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2985,11 +2985,11 @@
 	return 0;
 }
 
-static int git_apply_config(const char *var, const char *value)
+static int git_apply_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "apply.whitespace"))
 		return git_config_string(&apply_default_whitespace, var, value);
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 
@@ -3005,7 +3005,7 @@
 
 	prefix = setup_git_directory_gently(&is_not_gitdir);
 	prefix_length = prefix ? strlen(prefix) : 0;
-	git_config(git_apply_config);
+	git_config(git_apply_config, NULL);
 	if (apply_default_whitespace)
 		parse_whitespace_option(apply_default_whitespace);
 
diff --git a/builtin-blame.c b/builtin-blame.c
index bfd562d..b451f6c 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1993,7 +1993,7 @@
 		usage(blame_usage);
 }
 
-static int git_blame_config(const char *var, const char *value)
+static int git_blame_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "blame.showroot")) {
 		show_root = git_config_bool(var, value);
@@ -2003,7 +2003,7 @@
 		blank_boundary = git_config_bool(var, value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static struct commit *fake_working_tree_commit(const char *path, const char *contents_from)
@@ -2141,7 +2141,7 @@
 
 	cmd_is_annotate = !strcmp(argv[0], "annotate");
 
-	git_config(git_blame_config);
+	git_config(git_blame_config, NULL);
 	save_commit_buffer = 0;
 
 	opt = 0;
diff --git a/builtin-branch.c b/builtin-branch.c
index 19c508a..d279702 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -63,7 +63,7 @@
 	die("bad config variable '%s'", var);
 }
 
-static int git_branch_config(const char *var, const char *value)
+static int git_branch_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "color.branch")) {
 		branch_use_color = git_config_colorbool(var, value, -1);
@@ -76,7 +76,7 @@
 		color_parse(value, var, branch_colors[slot]);
 		return 0;
 	}
-	return git_color_default_config(var, value);
+	return git_color_default_config(var, value, cb);
 }
 
 static const char *branch_get_color(enum color_branch ix)
@@ -461,7 +461,7 @@
 		OPT_END(),
 	};
 
-	git_config(git_branch_config);
+	git_config(git_branch_config, NULL);
 
 	if (branch_use_color == -1)
 		branch_use_color = git_use_color_default;
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index 5ef15a4..200345e 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -222,7 +222,7 @@
 		OPT_END()
 	};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	if (argc != 3 && argc != 2)
 		usage_with_options(cat_file_usage, options);
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 7e42024..eb1fc9a 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -166,7 +166,7 @@
 	int read_from_stdin = 0;
 	int prefix_length;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	state.base_dir = "";
 	prefix_length = prefix ? strlen(prefix) : 0;
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 68fffd2..1ea017f 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -516,7 +516,7 @@
 	memset(&opts, 0, sizeof(opts));
 	memset(&new, 0, sizeof(new));
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	opts.track = git_branch_track;
 
diff --git a/builtin-clean.c b/builtin-clean.c
index 6778a03..80a7ff9 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -19,11 +19,11 @@
 	NULL
 };
 
-static int git_clean_config(const char *var, const char *value)
+static int git_clean_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "clean.requireforce"))
 		force = !git_config_bool(var, value);
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 int cmd_clean(int argc, const char **argv, const char *prefix)
@@ -50,7 +50,7 @@
 		OPT_END()
 	};
 
-	git_config(git_clean_config);
+	git_config(git_clean_config, NULL);
 	if (force < 0)
 		force = 0;
 	else
diff --git a/builtin-clone.c b/builtin-clone.c
index 2a3f673..4740b13 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -418,7 +418,7 @@
 	if (option_reference)
 		setup_reference(git_dir);
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	if (option_bare) {
 		strcpy(branch_top, "refs/heads/");
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 6610d18..e5e4bdb 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -60,7 +60,7 @@
 	struct strbuf buffer;
 	int encoding_is_utf8;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	if (argc < 2)
 		usage(commit_tree_usage);
diff --git a/builtin-commit.c b/builtin-commit.c
index d752243..07872c8 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -806,7 +806,7 @@
 	const char *index_file;
 	int commitable;
 
-	git_config(git_status_config);
+	git_config(git_status_config, NULL);
 
 	if (wt_status_use_color == -1)
 		wt_status_use_color = git_use_color_default;
@@ -860,7 +860,7 @@
 	}
 }
 
-int git_commit_config(const char *k, const char *v)
+int git_commit_config(const char *k, const char *v, void *cb)
 {
 	if (!strcmp(k, "commit.template")) {
 		if (!v)
@@ -869,7 +869,7 @@
 		return 0;
 	}
 
-	return git_status_config(k, v);
+	return git_status_config(k, v, cb);
 }
 
 static const char commit_utf8_warn[] =
@@ -897,7 +897,7 @@
 	unsigned char commit_sha1[20];
 	struct ref_lock *ref_lock;
 
-	git_config(git_commit_config);
+	git_config(git_commit_config, NULL);
 
 	argc = parse_and_validate_options(argc, argv, builtin_commit_usage);
 
diff --git a/builtin-config.c b/builtin-config.c
index 8ee01bd..3a441ef 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -18,7 +18,7 @@
 static char term = '\n';
 static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;
 
-static int show_all_config(const char *key_, const char *value_)
+static int show_all_config(const char *key_, const char *value_, void *cb)
 {
 	if (value_)
 		printf("%s%c%s%c", key_, delim, value_, term);
@@ -27,7 +27,7 @@
 	return 0;
 }
 
-static int show_config(const char* key_, const char* value_)
+static int show_config(const char* key_, const char* value_, void *cb)
 {
 	char value[256];
 	const char *vptr = value;
@@ -121,14 +121,14 @@
 	}
 
 	if (do_all && system_wide)
-		git_config_from_file(show_config, system_wide);
+		git_config_from_file(show_config, system_wide, NULL);
 	if (do_all && global)
-		git_config_from_file(show_config, global);
-	git_config_from_file(show_config, local);
+		git_config_from_file(show_config, global, NULL);
+	git_config_from_file(show_config, local, NULL);
 	if (!do_all && !seen && global)
-		git_config_from_file(show_config, global);
+		git_config_from_file(show_config, global, NULL);
 	if (!do_all && !seen && system_wide)
-		git_config_from_file(show_config, system_wide);
+		git_config_from_file(show_config, system_wide, NULL);
 
 	free(key);
 	if (regexp) {
@@ -182,7 +182,7 @@
 static const char *get_color_slot;
 static char parsed_color[COLOR_MAXLEN];
 
-static int git_get_color_config(const char *var, const char *value)
+static int git_get_color_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, get_color_slot)) {
 		if (!value)
@@ -218,7 +218,7 @@
 
 	get_color_found = 0;
 	parsed_color[0] = '\0';
-	git_config(git_get_color_config);
+	git_config(git_get_color_config, NULL);
 
 	if (!get_color_found && def_color)
 		color_parse(def_color, "command line", parsed_color);
@@ -230,7 +230,8 @@
 static int stdout_is_tty;
 static int get_colorbool_found;
 static int get_diff_color_found;
-static int git_get_colorbool_config(const char *var, const char *value)
+static int git_get_colorbool_config(const char *var, const char *value,
+		void *cb)
 {
 	if (!strcmp(var, get_color_slot)) {
 		get_colorbool_found =
@@ -265,7 +266,7 @@
 	get_colorbool_found = -1;
 	get_diff_color_found = -1;
 	get_color_slot = argv[0];
-	git_config(git_get_colorbool_config);
+	git_config(git_get_colorbool_config, NULL);
 
 	if (get_colorbool_found < 0) {
 		if (!strcmp(get_color_slot, "color.diff"))
@@ -298,7 +299,8 @@
 		else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) {
 			if (argc != 2)
 				usage(git_config_set_usage);
-			if (git_config(show_all_config) < 0 && file && errno)
+			if (git_config(show_all_config, NULL) < 0 &&
+					file && errno)
 				die("unable to read config file %s: %s", file,
 				    strerror(errno));
 			return 0;
diff --git a/builtin-diff-files.c b/builtin-diff-files.c
index e2306c1..907392a 100644
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
@@ -21,7 +21,7 @@
 
 	prefix = setup_git_directory_gently(&nongit);
 	init_revisions(&rev, prefix);
-	git_config(git_diff_basic_config); /* no "diff" UI options */
+	git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 	rev.abbrev = 0;
 
 	if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))
diff --git a/builtin-diff-index.c b/builtin-diff-index.c
index 2b955de..2f44ebf 100644
--- a/builtin-diff-index.c
+++ b/builtin-diff-index.c
@@ -17,7 +17,7 @@
 	int result;
 
 	init_revisions(&rev, prefix);
-	git_config(git_diff_basic_config); /* no "diff" UI options */
+	git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 	rev.abbrev = 0;
 
 	argc = setup_revisions(argc, argv, &rev, NULL);
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 832797f..9d2a48f 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -68,7 +68,7 @@
 	int read_stdin = 0;
 
 	init_revisions(opt, prefix);
-	git_config(git_diff_basic_config); /* no "diff" UI options */
+	git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
 	nr_sha1 = 0;
 	opt->abbrev = 0;
 	opt->diff = 1;
diff --git a/builtin-diff.c b/builtin-diff.c
index 7c2a841..583291a 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -234,7 +234,7 @@
 	 */
 
 	prefix = setup_git_directory_gently(&nongit);
-	git_config(git_diff_ui_config);
+	git_config(git_diff_ui_config, NULL);
 
 	if (diff_use_color_default == -1)
 		diff_use_color_default = git_use_color_default;
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index e1c5630..ff759cc 100755
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -372,7 +372,7 @@
 	};
 
 	/* we handle encodings */
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	init_revisions(&revs, prefix);
 	argc = setup_revisions(argc, argv, &revs, NULL);
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index c97a427..de1e8d1 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -635,7 +635,7 @@
 	return dst;
 }
 
-static int fetch_pack_config(const char *var, const char *value)
+static int fetch_pack_config(const char *var, const char *value, void *cb)
 {
 	if (strcmp(var, "fetch.unpacklimit") == 0) {
 		fetch_unpack_limit = git_config_int(var, value);
@@ -647,7 +647,7 @@
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static struct lock_file lock;
@@ -657,7 +657,7 @@
 	static int did_setup;
 	if (did_setup)
 		return;
-	git_config(fetch_pack_config);
+	git_config(fetch_pack_config, NULL);
 	if (0 <= transfer_unpack_limit)
 		unpack_limit = transfer_unpack_limit;
 	else if (0 <= fetch_unpack_limit)
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index b72cb59..b892621 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -10,7 +10,7 @@
 
 static int merge_summary;
 
-static int fmt_merge_msg_config(const char *key, const char *value)
+static int fmt_merge_msg_config(const char *key, const char *value, void *cb)
 {
 	static int found_merge_log = 0;
 	if (!strcmp("merge.log", key)) {
@@ -260,7 +260,7 @@
 	unsigned char head_sha1[20];
 	const char *current_branch;
 
-	git_config(fmt_merge_msg_config);
+	git_config(fmt_merge_msg_config, NULL);
 
 	while (argc > 1) {
 		if (!strcmp(argv[1], "--log") || !strcmp(argv[1], "--summary"))
diff --git a/builtin-gc.c b/builtin-gc.c
index 48f7d95..f5625bb 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -35,7 +35,7 @@
 static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
 static const char *argv_rerere[] = {"rerere", "gc", NULL};
 
-static int gc_config(const char *var, const char *value)
+static int gc_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "gc.packrefs")) {
 		if (value && !strcmp(value, "notbare"))
@@ -67,7 +67,7 @@
 		prune_expire = xstrdup(value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static void append_option(const char **cmd, const char *opt, int max_length)
@@ -226,7 +226,7 @@
 		OPT_END()
 	};
 
-	git_config(gc_config);
+	git_config(gc_config, NULL);
 
 	if (pack_refs < 0)
 		pack_refs = !is_bare_repository();
diff --git a/builtin-http-fetch.c b/builtin-http-fetch.c
index b1f3389..3a06248 100644
--- a/builtin-http-fetch.c
+++ b/builtin-http-fetch.c
@@ -18,7 +18,7 @@
 	int get_verbosely = 0;
 	int get_recover = 0;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	while (arg < argc && argv[arg][0] == '-') {
 		if (argv[arg][1] == 't') {
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 3968c99..d8bdf92 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -144,7 +144,7 @@
 	strcpy(template_path + template_len, "config");
 	repository_format_version = 0;
 	git_config_from_file(check_repository_format_version,
-			     template_path);
+			     template_path, NULL);
 	template_path[template_len] = 0;
 
 	if (repository_format_version &&
@@ -198,7 +198,7 @@
 	 */
 	copy_templates(template_path);
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	/*
 	 * We would have created the above under user's umask -- under
diff --git a/builtin-log.c b/builtin-log.c
index 543855b..9817d6f 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -230,7 +230,7 @@
 	return 0;
 }
 
-static int git_log_config(const char *var, const char *value)
+static int git_log_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "format.pretty"))
 		return git_config_string(&fmt_pretty, var, value);
@@ -246,14 +246,14 @@
 		default_show_root = git_config_bool(var, value);
 		return 0;
 	}
-	return git_diff_ui_config(var, value);
+	return git_diff_ui_config(var, value, cb);
 }
 
 int cmd_whatchanged(int argc, const char **argv, const char *prefix)
 {
 	struct rev_info rev;
 
-	git_config(git_log_config);
+	git_config(git_log_config, NULL);
 
 	if (diff_use_color_default == -1)
 		diff_use_color_default = git_use_color_default;
@@ -329,7 +329,7 @@
 	struct object_array_entry *objects;
 	int i, count, ret = 0;
 
-	git_config(git_log_config);
+	git_config(git_log_config, NULL);
 
 	if (diff_use_color_default == -1)
 		diff_use_color_default = git_use_color_default;
@@ -393,7 +393,7 @@
 {
 	struct rev_info rev;
 
-	git_config(git_log_config);
+	git_config(git_log_config, NULL);
 
 	if (diff_use_color_default == -1)
 		diff_use_color_default = git_use_color_default;
@@ -426,7 +426,7 @@
 {
 	struct rev_info rev;
 
-	git_config(git_log_config);
+	git_config(git_log_config, NULL);
 
 	if (diff_use_color_default == -1)
 		diff_use_color_default = git_use_color_default;
@@ -481,7 +481,7 @@
 	extra_hdr[extra_hdr_nr++] = xstrndup(value, len);
 }
 
-static int git_format_config(const char *var, const char *value)
+static int git_format_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "format.headers")) {
 		if (!value)
@@ -514,7 +514,7 @@
 		return 0;
 	}
 
-	return git_log_config(var, value);
+	return git_log_config(var, value, cb);
 }
 
 
@@ -781,7 +781,7 @@
 	char *add_signoff = NULL;
 	struct strbuf buf;
 
-	git_config(git_format_config);
+	git_config(git_format_config, NULL);
 	init_revisions(&rev, prefix);
 	rev.commit_format = CMIT_FMT_EMAIL;
 	rev.verbose_header = 1;
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index dc7eab8..75ba422 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -437,7 +437,7 @@
 	memset(&dir, 0, sizeof(dir));
 	if (prefix)
 		prefix_offset = strlen(prefix);
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c
index 7abe333..f4a75dd 100644
--- a/builtin-ls-tree.c
+++ b/builtin-ls-tree.c
@@ -122,7 +122,7 @@
 	unsigned char sha1[20];
 	struct tree *tree;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	ls_tree_prefix = prefix;
 	if (prefix && *prefix)
 		chomp_prefix = strlen(prefix);
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index e1e094f..97c1ff9 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -968,7 +968,7 @@
 	/* NEEDSWORK: might want to do the optional .git/ directory
 	 * discovery
 	 */
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	def_charset = (git_commit_encoding ? git_commit_encoding : "utf-8");
 	metainfo_charset = def_charset;
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
index 0108e22..bcf9395 100644
--- a/builtin-merge-base.c
+++ b/builtin-merge-base.c
@@ -28,7 +28,7 @@
 	unsigned char rev1key[20], rev2key[20];
 	int show_all = 0;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	while (1 < argc && argv[1][0] == '-') {
 		const char *arg = argv[1];
diff --git a/builtin-merge-recursive.c b/builtin-merge-recursive.c
index 46e636f..362c290 100644
--- a/builtin-merge-recursive.c
+++ b/builtin-merge-recursive.c
@@ -1340,7 +1340,7 @@
 	return (struct commit *)object;
 }
 
-static int merge_config(const char *var, const char *value)
+static int merge_config(const char *var, const char *value, void *cb)
 {
 	if (!strcasecmp(var, "merge.verbosity")) {
 		verbosity = git_config_int(var, value);
@@ -1354,7 +1354,7 @@
 		merge_rename_limit = git_config_int(var, value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
@@ -1375,7 +1375,7 @@
 			subtree_merge = 1;
 	}
 
-	git_config(merge_config);
+	git_config(merge_config, NULL);
 	if (getenv("GIT_MERGE_VERBOSITY"))
 		verbosity = strtol(getenv("GIT_MERGE_VERBOSITY"), NULL, 10);
 
diff --git a/builtin-mv.c b/builtin-mv.c
index fb906b3..5530e11 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -81,7 +81,7 @@
 	struct path_list deleted = {NULL, 0, 0, 0};
 	struct path_list changed = {NULL, 0, 0, 0};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	newfd = hold_locked_index(&lock_file, 1);
 	if (read_cache() < 0)
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index 384da4d..cde5de5 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -195,7 +195,7 @@
 		OPT_END(),
 	};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, opts, name_rev_usage, 0);
 	if (!!all + !!transform_stdin + !!argc > 1) {
 		error("Specify either a list, or --all, not both!");
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index f43eb67..70d2f5d 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1760,7 +1760,7 @@
 	free(delta_list);
 }
 
-static int git_pack_config(const char *k, const char *v)
+static int git_pack_config(const char *k, const char *v, void *cb)
 {
 	if(!strcmp(k, "pack.window")) {
 		window = git_config_int(k, v);
@@ -1813,7 +1813,7 @@
 		pack_size_limit_cfg = git_config_ulong(k, v);
 		return 0;
 	}
-	return git_default_config(k, v);
+	return git_default_config(k, v, cb);
 }
 
 static void read_object_list_from_stdin(void)
@@ -2033,7 +2033,7 @@
 	rp_av[1] = "--objects"; /* --thin will make it --objects-edge */
 	rp_ac = 2;
 
-	git_config(git_pack_config);
+	git_config(git_pack_config, NULL);
 	if (!pack_compression_seen && core_compression_seen)
 		pack_compression_level = core_compression_level;
 
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 7ac3088..5a09e17 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -104,12 +104,10 @@
 	opts.src_index = &the_index;
 	opts.dst_index = &the_index;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	newfd = hold_locked_index(&lock_file, 1);
 
-	git_config(git_default_config);
-
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 280e24e..897d1dc 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -329,7 +329,7 @@
 	return 0;
 }
 
-static int reflog_expire_config(const char *var, const char *value)
+static int reflog_expire_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "gc.reflogexpire")) {
 		if (!value)
@@ -343,7 +343,7 @@
 		default_reflog_expire_unreachable = approxidate(value);
 		return 0;
 	}
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
@@ -352,7 +352,7 @@
 	unsigned long now = time(NULL);
 	int i, status, do_all;
 
-	git_config(reflog_expire_config);
+	git_config(reflog_expire_config, NULL);
 
 	save_commit_buffer = 0;
 	do_all = status = 0;
diff --git a/builtin-remote.c b/builtin-remote.c
index 8b63619e..99a34df 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -153,7 +153,7 @@
 
 static struct path_list branch_list;
 
-static int config_read_branches(const char *key, const char *value)
+static int config_read_branches(const char *key, const char *value, void *cb)
 {
 	if (!prefixcmp(key, "branch.")) {
 		char *name;
@@ -200,7 +200,7 @@
 {
 	if (branch_list.nr)
 		return;
-	git_config(config_read_branches);
+	git_config(config_read_branches, NULL);
 	sort_path_list(&branch_list);
 }
 
@@ -514,7 +514,7 @@
 	struct path_list *list;
 } remote_group;
 
-static int get_remote_group(const char *key, const char *value)
+static int get_remote_group(const char *key, const char *value, void *cb)
 {
 	if (!prefixcmp(key, "remotes.") &&
 			!strcmp(key + 8, remote_group.name)) {
@@ -546,7 +546,7 @@
 	remote_group.list = &list;
 	for (i = 1; i < argc; i++) {
 		remote_group.name = argv[i];
-		result = git_config(get_remote_group);
+		result = git_config(get_remote_group, NULL);
 	}
 
 	if (!result && !list.nr  && argc == 2 && !strcmp(argv[1], "default"))
diff --git a/builtin-rerere.c b/builtin-rerere.c
index c607aad..5c81142 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -339,7 +339,7 @@
 	return write_rr(rr, fd);
 }
 
-static int git_rerere_config(const char *var, const char *value)
+static int git_rerere_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "gc.rerereresolved"))
 		cutoff_resolve = git_config_int(var, value);
@@ -348,7 +348,7 @@
 	else if (!strcmp(var, "rerere.enabled"))
 		rerere_enabled = git_config_bool(var, value);
 	else
-		return git_default_config(var, value);
+		return git_default_config(var, value, cb);
 	return 0;
 }
 
@@ -376,7 +376,7 @@
 {
 	int fd;
 
-	git_config(git_rerere_config);
+	git_config(git_rerere_config, NULL);
 	if (!is_rerere_enabled())
 		return -1;
 
diff --git a/builtin-reset.c b/builtin-reset.c
index 79424bb..e32ddd9 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -186,7 +186,7 @@
 		OPT_END()
 	};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	argc = parse_options(argc, argv, options, git_reset_usage,
 						PARSE_OPT_KEEP_DASHDASH);
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index b474527..83a7b134 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -591,7 +591,7 @@
 	int bisect_find_all = 0;
 	int quiet = 0;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	init_revisions(&revs, prefix);
 	revs.abbrev = 0;
 	revs.commit_format = CMIT_FMT_UNSPECIFIED;
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index ab3e850..a7860ed 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -387,7 +387,7 @@
 		return cmd_parseopt(argc - 1, argv + 1, prefix);
 
 	prefix = setup_git_directory();
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
diff --git a/builtin-revert.c b/builtin-revert.c
index 2b57525..0270f9b 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -269,7 +269,7 @@
 	const char *message, *encoding;
 	const char *defmsg = xstrdup(git_path("MERGE_MSG"));
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	me = action == REVERT ? "revert" : "cherry-pick";
 	setenv(GIT_REFLOG_ACTION, me, 0);
 	parse_args(argc, argv);
diff --git a/builtin-rm.c b/builtin-rm.c
index c0a8bb6..22c9bd1 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -144,7 +144,7 @@
 	const char **pathspec;
 	char *seen;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	newfd = hold_locked_index(&lock_file, 1);
 
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index 019abd3..ee4269d 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -533,7 +533,7 @@
 	die("bad sha1 reference %s", av);
 }
 
-static int git_show_branch_config(const char *var, const char *value)
+static int git_show_branch_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "showbranch.default")) {
 		if (!value)
@@ -547,7 +547,7 @@
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
@@ -611,7 +611,7 @@
 	int reflog = 0;
 	const char *reflog_base = NULL;
 
-	git_config(git_show_branch_config);
+	git_config(git_show_branch_config, NULL);
 
 	/* If nothing is specified, try the default first */
 	if (ac == 1 && default_num) {
diff --git a/builtin-symbolic-ref.c b/builtin-symbolic-ref.c
index d33982b..b49bdb6 100644
--- a/builtin-symbolic-ref.c
+++ b/builtin-symbolic-ref.c
@@ -35,7 +35,7 @@
 		OPT_END(),
 	};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, options, git_symbolic_ref_usage, 0);
 	if (msg &&!*msg)
 		die("Refusing to perform update with empty message");
diff --git a/builtin-tag.c b/builtin-tag.c
index 129ff57..e675206 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -256,7 +256,7 @@
 		die("signing key value too long (%.10s...)", value);
 }
 
-static int git_tag_config(const char *var, const char *value)
+static int git_tag_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "user.signingkey")) {
 		if (!value)
@@ -265,7 +265,7 @@
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static void write_tag_body(int fd, const unsigned char *sha1)
@@ -408,7 +408,7 @@
 		OPT_END()
 	};
 
-	git_config(git_tag_config);
+	git_config(git_tag_config, NULL);
 
 	argc = parse_options(argc, argv, options, git_tag_usage, 0);
 
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index fecf0be..85043d1 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -493,7 +493,7 @@
 	int i;
 	unsigned char sha1[20];
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	quiet = !isatty(2);
 
diff --git a/builtin-update-index.c b/builtin-update-index.c
index d4c85c0..9e0d7ab 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -567,7 +567,7 @@
 	int lock_error = 0;
 	struct lock_file *lock_file;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	/* We can't free this memory, it becomes part of a linked list parsed atexit() */
 	lock_file = xcalloc(1, sizeof(struct lock_file));
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index e90737c..93c1271 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -22,7 +22,7 @@
 		OPT_END(),
 	};
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, options, git_update_ref_usage, 0);
 	if (msg && !*msg)
 		die("Refusing to perform update with empty message.");
diff --git a/builtin-verify-pack.c b/builtin-verify-pack.c
index 4958bbb..4c515a0 100644
--- a/builtin-verify-pack.c
+++ b/builtin-verify-pack.c
@@ -55,7 +55,7 @@
 	int no_more_options = 0;
 	int nothing_done = 1;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	while (1 < argc) {
 		if (!no_more_options && argv[1][0] == '-') {
 			if (!strcmp("-v", argv[1]))
diff --git a/builtin-verify-tag.c b/builtin-verify-tag.c
index db81496..92eaa89 100644
--- a/builtin-verify-tag.c
+++ b/builtin-verify-tag.c
@@ -90,7 +90,7 @@
 {
 	int i = 1, verbose = 0, had_error = 0;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	if (argc == 1)
 		usage(builtin_verify_tag_usage);
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index e838d01..c218799 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -18,7 +18,7 @@
 	unsigned char sha1[20];
 	const char *me = "git-write-tree";
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	while (1 < argc) {
 		const char *arg = argv[1];
 		if (!strcmp(arg, "--missing-ok"))
diff --git a/cache.h b/cache.h
index 943bee9..eab1a17 100644
--- a/cache.h
+++ b/cache.h
@@ -723,10 +723,10 @@
 /* Dumb servers support */
 extern int update_server_info(int);
 
-typedef int (*config_fn_t)(const char *, const char *);
-extern int git_default_config(const char *, const char *);
-extern int git_config_from_file(config_fn_t fn, const char *);
-extern int git_config(config_fn_t fn);
+typedef int (*config_fn_t)(const char *, const char *, void *);
+extern int git_default_config(const char *, const char *, void *);
+extern int git_config_from_file(config_fn_t fn, const char *, void *);
+extern int git_config(config_fn_t fn, void *);
 extern int git_parse_long(const char *, long *);
 extern int git_parse_ulong(const char *, unsigned long *);
 extern int git_config_int(const char *, const char *);
@@ -738,7 +738,7 @@
 extern int git_config_set_multivar(const char *, const char *, const char *, int);
 extern int git_config_rename_section(const char *, const char *);
 extern const char *git_etc_gitconfig(void);
-extern int check_repository_format_version(const char *var, const char *value);
+extern int check_repository_format_version(const char *var, const char *value, void *cb);
 extern int git_env_bool(const char *, int);
 extern int git_config_system(void);
 extern int git_config_global(void);
diff --git a/color.c b/color.c
index 12a6453..fc0b72a 100644
--- a/color.c
+++ b/color.c
@@ -145,14 +145,14 @@
 	return 0;
 }
 
-int git_color_default_config(const char *var, const char *value)
+int git_color_default_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "color.ui")) {
 		git_use_color_default = git_config_colorbool(var, value, -1);
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int color_vfprintf(FILE *fp, const char *color, const char *fmt,
diff --git a/color.h b/color.h
index ecda556..6cf5c88 100644
--- a/color.h
+++ b/color.h
@@ -13,7 +13,7 @@
 /*
  * Use this instead of git_default_config if you need the value of color.ui.
  */
-int git_color_default_config(const char *var, const char *value);
+int git_color_default_config(const char *var, const char *value, void *cb);
 
 int git_config_colorbool(const char *var, const char *value, int stdout_is_tty);
 void color_parse(const char *var, const char *value, char *dst);
diff --git a/config.c b/config.c
index 5195de1..c2f2bbb 100644
--- a/config.c
+++ b/config.c
@@ -111,7 +111,7 @@
 	return isalnum(c) || c == '-';
 }
 
-static int get_value(config_fn_t fn, char *name, unsigned int len)
+static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
 {
 	int c;
 	char *value;
@@ -139,7 +139,7 @@
 		if (!value)
 			return -1;
 	}
-	return fn(name, value);
+	return fn(name, value, data);
 }
 
 static int get_extended_base_var(char *name, int baselen, int c)
@@ -197,7 +197,7 @@
 	}
 }
 
-static int git_parse_file(config_fn_t fn)
+static int git_parse_file(config_fn_t fn, void *data)
 {
 	int comment = 0;
 	int baselen = 0;
@@ -228,7 +228,7 @@
 		if (!isalpha(c))
 			break;
 		var[baselen] = tolower(c);
-		if (get_value(fn, var, baselen+1) < 0)
+		if (get_value(fn, data, var, baselen+1) < 0)
 			break;
 	}
 	die("bad config file line %d in %s", config_linenr, config_file_name);
@@ -332,7 +332,7 @@
 	return 0;
 }
 
-int git_default_config(const char *var, const char *value)
+int git_default_config(const char *var, const char *value, void *dummy)
 {
 	/* This needs a better name */
 	if (!strcmp(var, "core.filemode")) {
@@ -516,7 +516,7 @@
 	return 0;
 }
 
-int git_config_from_file(config_fn_t fn, const char *filename)
+int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 {
 	int ret;
 	FILE *f = fopen(filename, "r");
@@ -527,7 +527,7 @@
 		config_file_name = filename;
 		config_linenr = 1;
 		config_file_eof = 0;
-		ret = git_parse_file(fn);
+		ret = git_parse_file(fn, data);
 		fclose(f);
 		config_file_name = NULL;
 	}
@@ -565,7 +565,7 @@
 	return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
 }
 
-int git_config(config_fn_t fn)
+int git_config(config_fn_t fn, void *data)
 {
 	int ret = 0;
 	char *repo_config = NULL;
@@ -578,7 +578,8 @@
 	filename = getenv(CONFIG_ENVIRONMENT);
 	if (!filename) {
 		if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
-			ret += git_config_from_file(fn, git_etc_gitconfig());
+			ret += git_config_from_file(fn, git_etc_gitconfig(),
+				data);
 		home = getenv("HOME");
 		filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
 		if (!filename)
@@ -588,11 +589,11 @@
 	if (git_config_global() && home) {
 		char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
 		if (!access(user_config, R_OK))
-			ret = git_config_from_file(fn, user_config);
+			ret = git_config_from_file(fn, user_config, data);
 		free(user_config);
 	}
 
-	ret += git_config_from_file(fn, filename);
+	ret += git_config_from_file(fn, filename, data);
 	free(repo_config);
 	return ret;
 }
@@ -622,7 +623,7 @@
 		  !regexec(store.value_regex, value, 0, NULL, 0)));
 }
 
-static int store_aux(const char* key, const char* value)
+static int store_aux(const char* key, const char* value, void *cb)
 {
 	const char *ep;
 	size_t section_len;
@@ -951,7 +952,7 @@
 		 * As a side effect, we make sure to transform only a valid
 		 * existing config file.
 		 */
-		if (git_config_from_file(store_aux, config_filename)) {
+		if (git_config_from_file(store_aux, config_filename, NULL)) {
 			error("invalid config file %s", config_filename);
 			free(store.key);
 			if (store.value_regex != NULL) {
diff --git a/connect.c b/connect.c
index d12b105..e92af29 100644
--- a/connect.c
+++ b/connect.c
@@ -360,7 +360,8 @@
 static const char *rhost_name;
 static int rhost_len;
 
-static int git_proxy_command_options(const char *var, const char *value)
+static int git_proxy_command_options(const char *var, const char *value,
+		void *cb)
 {
 	if (!strcmp(var, "core.gitproxy")) {
 		const char *for_pos;
@@ -404,7 +405,7 @@
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int git_use_proxy(const char *host)
@@ -412,7 +413,7 @@
 	rhost_name = host;
 	rhost_len = strlen(host);
 	git_proxy_command = getenv("GIT_PROXY_COMMAND");
-	git_config(git_proxy_command_options);
+	git_config(git_proxy_command_options, NULL);
 	rhost_name = NULL;
 	return (git_proxy_command && *git_proxy_command);
 }
diff --git a/convert.c b/convert.c
index d8c94cb..1c66844 100644
--- a/convert.c
+++ b/convert.c
@@ -323,7 +323,7 @@
 	char *clean;
 } *user_convert, **user_convert_tail;
 
-static int read_convert_config(const char *var, const char *value)
+static int read_convert_config(const char *var, const char *value, void *cb)
 {
 	const char *ep, *name;
 	int namelen;
@@ -385,7 +385,7 @@
 		attr_ident = git_attr("ident", 5);
 		attr_filter = git_attr("filter", 6);
 		user_convert_tail = &user_convert;
-		git_config(read_convert_config);
+		git_config(read_convert_config, NULL);
 	}
 	check[0].attr = attr_crlf;
 	check[1].attr = attr_ident;
diff --git a/daemon.c b/daemon.c
index 2b4a6f1..63cd12c 100644
--- a/daemon.c
+++ b/daemon.c
@@ -306,7 +306,7 @@
 static struct daemon_service *service_looking_at;
 static int service_enabled;
 
-static int git_daemon_config(const char *var, const char *value)
+static int git_daemon_config(const char *var, const char *value, void *cb)
 {
 	if (!prefixcmp(var, "daemon.") &&
 	    !strcmp(var + 7, service_looking_at->config_name)) {
@@ -356,7 +356,7 @@
 	if (service->overridable) {
 		service_looking_at = service;
 		service_enabled = -1;
-		git_config(git_daemon_config);
+		git_config(git_daemon_config, NULL);
 		if (0 <= service_enabled)
 			enabled = service_enabled;
 	}
diff --git a/diff.c b/diff.c
index d57bc29..62fdc54 100644
--- a/diff.c
+++ b/diff.c
@@ -129,7 +129,7 @@
  * never be affected by the setting of diff.renames
  * the user happens to have in the configuration file.
  */
-int git_diff_ui_config(const char *var, const char *value)
+int git_diff_ui_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "diff.renamelimit")) {
 		diff_rename_limit_default = git_config_int(var, value);
@@ -166,10 +166,10 @@
 			return parse_lldiff_command(var, ep, value);
 	}
 
-	return git_diff_basic_config(var, value);
+	return git_diff_basic_config(var, value, cb);
 }
 
-int git_diff_basic_config(const char *var, const char *value)
+int git_diff_basic_config(const char *var, const char *value, void *cb)
 {
 	if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
 		int slot = parse_diff_color_slot(var, 11);
@@ -190,7 +190,7 @@
 		}
 	}
 
-	return git_color_default_config(var, value);
+	return git_color_default_config(var, value, cb);
 }
 
 static char *quote_two(const char *one, const char *two)
diff --git a/diff.h b/diff.h
index 1dfe1f9..b0b700a 100644
--- a/diff.h
+++ b/diff.h
@@ -182,8 +182,8 @@
 #define DIFF_SETUP_USE_CACHE		2
 #define DIFF_SETUP_USE_SIZE_CACHE	4
 
-extern int git_diff_basic_config(const char *var, const char *value);
-extern int git_diff_ui_config(const char *var, const char *value);
+extern int git_diff_basic_config(const char *var, const char *value, void *cb);
+extern int git_diff_ui_config(const char *var, const char *value, void *cb);
 extern int diff_use_color_default;
 extern void diff_setup(struct diff_options *);
 extern int diff_opt_parse(struct diff_options *, const char **, int);
diff --git a/fast-import.c b/fast-import.c
index caea684..93119bb 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2352,7 +2352,7 @@
 	fclose(f);
 }
 
-static int git_pack_config(const char *k, const char *v)
+static int git_pack_config(const char *k, const char *v, void *cb)
 {
 	if (!strcmp(k, "pack.depth")) {
 		max_depth = git_config_int(k, v);
@@ -2370,7 +2370,7 @@
 		pack_compression_seen = 1;
 		return 0;
 	}
-	return git_default_config(k, v);
+	return git_default_config(k, v, cb);
 }
 
 static const char fast_import_usage[] =
@@ -2381,7 +2381,7 @@
 	unsigned int i, show_stats = 1;
 
 	setup_git_directory();
-	git_config(git_pack_config);
+	git_config(git_pack_config, NULL);
 	if (!pack_compression_seen && core_compression_seen)
 		pack_compression_level = core_compression_level;
 
diff --git a/hash-object.c b/hash-object.c
index 0a7ac2f..48d5223 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -65,7 +65,7 @@
 	int hashstdin = 0;
 	int stdin_paths = 0;
 
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	for (i = 1 ; i < argc; i++) {
 		if (!no_more_flags && argv[i][0] == '-') {
diff --git a/help.c b/help.c
index af80979..d89d437 100644
--- a/help.c
+++ b/help.c
@@ -252,7 +252,7 @@
 	return 0;
 }
 
-static int git_help_config(const char *var, const char *value)
+static int git_help_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "help.format")) {
 		if (!value)
@@ -269,7 +269,7 @@
 	if (!prefixcmp(var, "man."))
 		return add_man_viewer_info(var, value);
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 /* most GUI terminals set COLUMNS (although some don't export it) */
@@ -641,7 +641,7 @@
 	const char *alias;
 
 	setup_git_directory_gently(&nongit);
-	git_config(git_help_config);
+	git_config(git_help_config, NULL);
 
 	argc = parse_options(argc, argv, builtin_help_options,
 			builtin_help_usage, 0);
diff --git a/http.c b/http.c
index acf746a..2a21ccb 100644
--- a/http.c
+++ b/http.c
@@ -90,7 +90,7 @@
 }
 #endif
 
-static int http_options(const char *var, const char *value)
+static int http_options(const char *var, const char *value, void *cb)
 {
 	if (!strcmp("http.sslverify", var)) {
 		if (curl_ssl_verify == -1) {
@@ -169,7 +169,7 @@
 	}
 
 	/* Fall back on the default ones */
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static CURL* get_curl_handle(void)
@@ -263,7 +263,7 @@
 	if (low_speed_time != NULL)
 		curl_low_speed_time = strtol(low_speed_time, NULL, 10);
 
-	git_config(http_options);
+	git_config(http_options, NULL);
 
 	if (curl_ssl_verify == -1)
 		curl_ssl_verify = 1;
diff --git a/imap-send.c b/imap-send.c
index db65597..1ec1310 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1247,7 +1247,7 @@
 static char *imap_folder;
 
 static int
-git_imap_config(const char *key, const char *val)
+git_imap_config(const char *key, const char *val, void *cb)
 {
 	char imap_key[] = "imap.";
 
@@ -1296,7 +1296,7 @@
 	/* init the random number generator */
 	arc4_init();
 
-	git_config( git_imap_config );
+	git_config(git_imap_config, NULL);
 
 	if (!imap_folder) {
 		fprintf( stderr, "no imap store specified\n" );
diff --git a/index-pack.c b/index-pack.c
index 9c0c278..aaba944 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -765,7 +765,7 @@
 	}
 }
 
-static int git_index_pack_config(const char *k, const char *v)
+static int git_index_pack_config(const char *k, const char *v, void *cb)
 {
 	if (!strcmp(k, "pack.indexversion")) {
 		pack_idx_default_version = git_config_int(k, v);
@@ -773,7 +773,7 @@
 			die("bad pack.indexversion=%d", pack_idx_default_version);
 		return 0;
 	}
-	return git_default_config(k, v);
+	return git_default_config(k, v, cb);
 }
 
 int main(int argc, char **argv)
@@ -786,7 +786,7 @@
 	struct pack_idx_entry **idx_objects;
 	unsigned char sha1[20];
 
-	git_config(git_index_pack_config);
+	git_config(git_index_pack_config, NULL);
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
diff --git a/ll-merge.c b/ll-merge.c
index 5ae7433..9837c84 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -225,7 +225,7 @@
 static struct ll_merge_driver *ll_user_merge, **ll_user_merge_tail;
 static const char *default_ll_merge;
 
-static int read_merge_config(const char *var, const char *value)
+static int read_merge_config(const char *var, const char *value, void *cb)
 {
 	struct ll_merge_driver *fn;
 	const char *ep, *name;
@@ -309,7 +309,7 @@
 	if (ll_user_merge_tail)
 		return;
 	ll_user_merge_tail = &ll_user_merge;
-	git_config(read_merge_config);
+	git_config(read_merge_config, NULL);
 }
 
 static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr)
diff --git a/pager.c b/pager.c
index ca002f9..dbd9414 100644
--- a/pager.c
+++ b/pager.c
@@ -33,7 +33,7 @@
 		return;
 	if (!pager) {
 		if (!pager_program)
-			git_config(git_default_config);
+			git_config(git_default_config, NULL);
 		pager = pager_program;
 	}
 	if (!pager)
diff --git a/receive-pack.c b/receive-pack.c
index 828d490..b26f2e3 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -19,7 +19,7 @@
 static char capabilities[] = " report-status delete-refs ";
 static int capabilities_sent;
 
-static int receive_pack_config(const char *var, const char *value)
+static int receive_pack_config(const char *var, const char *value, void *cb)
 {
 	if (strcmp(var, "receive.denynonfastforwards") == 0) {
 		deny_non_fast_forwards = git_config_bool(var, value);
@@ -41,7 +41,7 @@
 		return 0;
 	}
 
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
@@ -489,7 +489,7 @@
 	if (is_repository_shallow())
 		die("attempt to push into a shallow repository");
 
-	git_config(receive_pack_config);
+	git_config(receive_pack_config, NULL);
 
 	if (0 <= transfer_unpack_limit)
 		unpack_limit = transfer_unpack_limit;
diff --git a/remote.c b/remote.c
index 75a12c0..91e3b11 100644
--- a/remote.c
+++ b/remote.c
@@ -298,7 +298,7 @@
 	remote->fetch_tags = 1; /* always auto-follow */
 }
 
-static int handle_config(const char *key, const char *value)
+static int handle_config(const char *key, const char *value, void *cb)
 {
 	const char *name;
 	const char *subkey;
@@ -420,7 +420,7 @@
 		current_branch =
 			make_branch(head_ref + strlen("refs/heads/"), 0);
 	}
-	git_config(handle_config);
+	git_config(handle_config, NULL);
 	alias_all_urls();
 }
 
diff --git a/setup.c b/setup.c
index b8fd476..d630e37 100644
--- a/setup.c
+++ b/setup.c
@@ -300,7 +300,7 @@
 
 static int check_repository_format_gently(int *nongit_ok)
 {
-	git_config(check_repository_format_version);
+	git_config(check_repository_format_version, NULL);
 	if (GIT_REPO_VERSION < repository_format_version) {
 		if (!nongit_ok)
 			die ("Expected git repo version <= %d, found %d",
@@ -524,7 +524,7 @@
 	return i & 0666;
 }
 
-int check_repository_format_version(const char *var, const char *value)
+int check_repository_format_version(const char *var, const char *value, void *cb)
 {
 	if (strcmp(var, "core.repositoryformatversion") == 0)
 		repository_format_version = git_config_int(var, value);
diff --git a/unpack-file.c b/unpack-file.c
index 65c66eb..bcdc8bb 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -31,7 +31,7 @@
 		die("Not a valid object name %s", argv[1]);
 
 	setup_git_directory();
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 
 	puts(create_temp_file(sha1));
 	return 0;
diff --git a/var.c b/var.c
index c20ac91..724ba87 100644
--- a/var.c
+++ b/var.c
@@ -39,13 +39,13 @@
 	return val;
 }
 
-static int show_config(const char *var, const char *value)
+static int show_config(const char *var, const char *value, void *cb)
 {
 	if (value)
 		printf("%s=%s\n", var, value);
 	else
 		printf("%s\n", var);
-	return git_default_config(var, value);
+	return git_default_config(var, value, cb);
 }
 
 int main(int argc, char **argv)
@@ -60,11 +60,11 @@
 	val = NULL;
 
 	if (strcmp(argv[1], "-l") == 0) {
-		git_config(show_config);
+		git_config(show_config, NULL);
 		list_vars();
 		return 0;
 	}
-	git_config(git_default_config);
+	git_config(git_default_config, NULL);
 	val = read_var(argv[1]);
 	if (!val)
 		usage(var_usage);
diff --git a/wt-status.c b/wt-status.c
index 6e6516c..5b4d74c 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -367,7 +367,7 @@
 	}
 }
 
-int git_status_config(const char *k, const char *v)
+int git_status_config(const char *k, const char *v, void *cb)
 {
 	if (!strcmp(k, "status.submodulesummary")) {
 		int is_bool;
@@ -391,5 +391,5 @@
 		wt_status_relative_paths = git_config_bool(k, v);
 		return 0;
 	}
-	return git_color_default_config(k, v);
+	return git_color_default_config(k, v, cb);
 }
diff --git a/wt-status.h b/wt-status.h
index f0675fd..597c7ea 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -28,7 +28,7 @@
 	const char *prefix;
 };
 
-int git_status_config(const char *var, const char *value);
+int git_status_config(const char *var, const char *value, void *cb);
 extern int wt_status_use_color;
 extern int wt_status_relative_paths;
 void wt_status_prepare(struct wt_status *s);