]> git.ipfire.org Git - thirdparty/git.git/blobdiff - config.c
Git 2.47-rc0
[thirdparty/git.git] / config.c
index ae3652b08fa6f36af6c085e36b89efdd46d72389..1266eab08607155c1fd4ce2a9734243839d3f7bc 100644 (file)
--- a/config.c
+++ b/config.c
@@ -5,6 +5,9 @@
  * Copyright (C) Johannes Schindelin, 2005
  *
  */
  * Copyright (C) Johannes Schindelin, 2005
  *
  */
+
+#define USE_THE_REPOSITORY_VARIABLE
+
 #include "git-compat-util.h"
 #include "abspath.h"
 #include "advice.h"
 #include "git-compat-util.h"
 #include "abspath.h"
 #include "advice.h"
@@ -125,7 +128,7 @@ struct config_include_data {
        config_fn_t fn;
        void *data;
        const struct config_options *opts;
        config_fn_t fn;
        void *data;
        const struct config_options *opts;
-       struct git_config_source *config_source;
+       const struct git_config_source *config_source;
        struct repository *repo;
 
        /*
        struct repository *repo;
 
        /*
@@ -297,13 +300,15 @@ done:
        return ret;
 }
 
        return ret;
 }
 
-static int include_by_branch(const char *cond, size_t cond_len)
+static int include_by_branch(struct config_include_data *data,
+                            const char *cond, size_t cond_len)
 {
        int flags;
        int ret;
        struct strbuf pattern = STRBUF_INIT;
 {
        int flags;
        int ret;
        struct strbuf pattern = STRBUF_INIT;
-       const char *refname = !the_repository->gitdir ?
-               NULL : resolve_ref_unsafe("HEAD", 0, NULL, &flags);
+       const char *refname = (!data->repo || !data->repo->gitdir) ?
+               NULL : refs_resolve_ref_unsafe(get_main_ref_store(data->repo),
+                                              "HEAD", 0, NULL, &flags);
        const char *shortname;
 
        if (!refname || !(flags & REF_ISSYMREF) ||
        const char *shortname;
 
        if (!refname || !(flags & REF_ISSYMREF) ||
@@ -402,7 +407,7 @@ static int include_condition_is_true(const struct key_value_info *kvi,
        else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
                return include_by_gitdir(kvi, opts, cond, cond_len, 1);
        else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
        else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
                return include_by_gitdir(kvi, opts, cond, cond_len, 1);
        else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
-               return include_by_branch(cond, cond_len);
+               return include_by_branch(inc, cond, cond_len);
        else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
                                   &cond_len))
                return include_by_remote_url(inc, cond, cond_len);
        else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
                                   &cond_len))
                return include_by_remote_url(inc, cond, cond_len);
@@ -1243,6 +1248,15 @@ ssize_t git_config_ssize_t(const char *name, const char *value,
        return ret;
 }
 
        return ret;
 }
 
+double git_config_double(const char *name, const char *value,
+                        const struct key_value_info *kvi)
+{
+       double ret;
+       if (!git_parse_double(value, &ret))
+               die_bad_number(name, value, kvi);
+       return ret;
+}
+
 static const struct fsync_component_name {
        const char *name;
        enum fsync_component component_bits;
 static const struct fsync_component_name {
        const char *name;
        enum fsync_component component_bits;
@@ -1337,7 +1351,7 @@ int git_config_bool(const char *name, const char *value)
        return v;
 }
 
        return v;
 }
 
-int git_config_string(const char **dest, const char *var, const char *value)
+int git_config_string(char **dest, const char *var, const char *value)
 {
        if (!value)
                return config_error_nonbool(var);
 {
        if (!value)
                return config_error_nonbool(var);
@@ -1345,7 +1359,7 @@ int git_config_string(const char **dest, const char *var, const char *value)
        return 0;
 }
 
        return 0;
 }
 
-int git_config_pathname(const char **dest, const char *var, const char *value)
+int git_config_pathname(char **dest, const char *var, const char *value)
 {
        if (!value)
                return config_error_nonbool(var);
 {
        if (!value)
                return config_error_nonbool(var);
@@ -1413,11 +1427,15 @@ static int git_default_core_config(const char *var, const char *value,
                return 0;
        }
 
                return 0;
        }
 
-       if (!strcmp(var, "core.attributesfile"))
+       if (!strcmp(var, "core.attributesfile")) {
+               FREE_AND_NULL(git_attributes_file);
                return git_config_pathname(&git_attributes_file, var, value);
                return git_config_pathname(&git_attributes_file, var, value);
+       }
 
 
-       if (!strcmp(var, "core.hookspath"))
+       if (!strcmp(var, "core.hookspath")) {
+               FREE_AND_NULL(git_hooks_path);
                return git_config_pathname(&git_hooks_path, var, value);
                return git_config_pathname(&git_hooks_path, var, value);
+       }
 
        if (!strcmp(var, "core.bare")) {
                is_bare_repository_cfg = git_config_bool(var, value);
 
        if (!strcmp(var, "core.bare")) {
                is_bare_repository_cfg = git_config_bool(var, value);
@@ -1429,36 +1447,16 @@ static int git_default_core_config(const char *var, const char *value,
                return 0;
        }
 
                return 0;
        }
 
-       if (!strcmp(var, "core.prefersymlinkrefs")) {
-               prefer_symlink_refs = git_config_bool(var, value);
-               return 0;
-       }
-
-       if (!strcmp(var, "core.logallrefupdates")) {
-               if (value && !strcasecmp(value, "always"))
-                       log_all_ref_updates = LOG_REFS_ALWAYS;
-               else if (git_config_bool(var, value))
-                       log_all_ref_updates = LOG_REFS_NORMAL;
-               else
-                       log_all_ref_updates = LOG_REFS_NONE;
-               return 0;
-       }
-
-       if (!strcmp(var, "core.warnambiguousrefs")) {
-               warn_ambiguous_refs = git_config_bool(var, value);
-               return 0;
-       }
-
        if (!strcmp(var, "core.abbrev")) {
                if (!value)
                        return config_error_nonbool(var);
                if (!strcasecmp(value, "auto"))
                        default_abbrev = -1;
                else if (!git_parse_maybe_bool_text(value))
        if (!strcmp(var, "core.abbrev")) {
                if (!value)
                        return config_error_nonbool(var);
                if (!strcasecmp(value, "auto"))
                        default_abbrev = -1;
                else if (!git_parse_maybe_bool_text(value))
-                       default_abbrev = the_hash_algo->hexsz;
+                       default_abbrev = GIT_MAX_HEXSZ;
                else {
                        int abbrev = git_config_int(var, value, ctx->kvi);
                else {
                        int abbrev = git_config_int(var, value, ctx->kvi);
-                       if (abbrev < minimum_abbrev || abbrev > the_hash_algo->hexsz)
+                       if (abbrev < minimum_abbrev)
                                return error(_("abbrev length out of range: %d"), abbrev);
                        default_abbrev = abbrev;
                }
                                return error(_("abbrev length out of range: %d"), abbrev);
                        default_abbrev = abbrev;
                }
@@ -1552,18 +1550,15 @@ static int git_default_core_config(const char *var, const char *value,
                return 0;
        }
 
                return 0;
        }
 
-       if (!strcmp(var, "core.checkroundtripencoding"))
+       if (!strcmp(var, "core.checkroundtripencoding")) {
+               FREE_AND_NULL(check_roundtrip_encoding);
                return git_config_string(&check_roundtrip_encoding, var, value);
                return git_config_string(&check_roundtrip_encoding, var, value);
-
-       if (!strcmp(var, "core.notesref")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               notes_ref_name = xstrdup(value);
-               return 0;
        }
 
        }
 
-       if (!strcmp(var, "core.editor"))
+       if (!strcmp(var, "core.editor")) {
+               FREE_AND_NULL(editor_program);
                return git_config_string(&editor_program, var, value);
                return git_config_string(&editor_program, var, value);
+       }
 
        if (!strcmp(var, "core.commentchar") ||
            !strcmp(var, "core.commentstring")) {
 
        if (!strcmp(var, "core.commentchar") ||
            !strcmp(var, "core.commentstring")) {
@@ -1574,18 +1569,21 @@ static int git_default_core_config(const char *var, const char *value,
                else if (value[0]) {
                        if (strchr(value, '\n'))
                                return error(_("%s cannot contain newline"), var);
                else if (value[0]) {
                        if (strchr(value, '\n'))
                                return error(_("%s cannot contain newline"), var);
-                       comment_line_str = xstrdup(value);
+                       comment_line_str = value;
+                       FREE_AND_NULL(comment_line_str_to_free);
                        auto_comment_line_char = 0;
                } else
                        return error(_("%s must have at least one character"), var);
                return 0;
        }
 
                        auto_comment_line_char = 0;
                } else
                        return error(_("%s must have at least one character"), var);
                return 0;
        }
 
-       if (!strcmp(var, "core.askpass"))
+       if (!strcmp(var, "core.askpass")) {
+               FREE_AND_NULL(askpass_program);
                return git_config_string(&askpass_program, var, value);
                return git_config_string(&askpass_program, var, value);
+       }
 
        if (!strcmp(var, "core.excludesfile")) {
 
        if (!strcmp(var, "core.excludesfile")) {
-               free((char *)excludes_file);
+               FREE_AND_NULL(excludes_file);
                return git_config_pathname(&excludes_file, var, value);
        }
 
                return git_config_pathname(&excludes_file, var, value);
        }
 
@@ -1688,11 +1686,15 @@ static int git_default_sparse_config(const char *var, const char *value)
 
 static int git_default_i18n_config(const char *var, const char *value)
 {
 
 static int git_default_i18n_config(const char *var, const char *value)
 {
-       if (!strcmp(var, "i18n.commitencoding"))
+       if (!strcmp(var, "i18n.commitencoding")) {
+               FREE_AND_NULL(git_commit_encoding);
                return git_config_string(&git_commit_encoding, var, value);
                return git_config_string(&git_commit_encoding, var, value);
+       }
 
 
-       if (!strcmp(var, "i18n.logoutputencoding"))
+       if (!strcmp(var, "i18n.logoutputencoding")) {
+               FREE_AND_NULL(git_log_output_encoding);
                return git_config_string(&git_log_output_encoding, var, value);
                return git_config_string(&git_log_output_encoding, var, value);
+       }
 
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
@@ -1765,10 +1767,15 @@ static int git_default_push_config(const char *var, const char *value)
 
 static int git_default_mailmap_config(const char *var, const char *value)
 {
 
 static int git_default_mailmap_config(const char *var, const char *value)
 {
-       if (!strcmp(var, "mailmap.file"))
+       if (!strcmp(var, "mailmap.file")) {
+               FREE_AND_NULL(git_mailmap_file);
                return git_config_pathname(&git_mailmap_file, var, value);
                return git_config_pathname(&git_mailmap_file, var, value);
-       if (!strcmp(var, "mailmap.blob"))
+       }
+
+       if (!strcmp(var, "mailmap.blob")) {
+               FREE_AND_NULL(git_mailmap_blob);
                return git_config_string(&git_mailmap_blob, var, value);
                return git_config_string(&git_mailmap_blob, var, value);
+       }
 
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
@@ -1776,8 +1783,10 @@ static int git_default_mailmap_config(const char *var, const char *value)
 
 static int git_default_attr_config(const char *var, const char *value)
 {
 
 static int git_default_attr_config(const char *var, const char *value)
 {
-       if (!strcmp(var, "attr.tree"))
+       if (!strcmp(var, "attr.tree")) {
+               FREE_AND_NULL(git_attr_tree);
                return git_config_string(&git_attr_tree, var, value);
                return git_config_string(&git_attr_tree, var, value);
+       }
 
        /*
         * Add other attribute related config variables here and to
 
        /*
         * Add other attribute related config variables here and to
@@ -2105,7 +2114,7 @@ static int do_git_config_sequence(const struct config_options *opts,
 }
 
 int config_with_options(config_fn_t fn, void *data,
 }
 
 int config_with_options(config_fn_t fn, void *data,
-                       struct git_config_source *config_source,
+                       const struct git_config_source *config_source,
                        struct repository *repo,
                        const struct config_options *opts)
 {
                        struct repository *repo,
                        const struct config_options *opts)
 {
@@ -2167,7 +2176,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data)
        }
 }
 
        }
 }
 
-void read_early_config(config_fn_t cb, void *data)
+void read_early_config(struct repository *repo, config_fn_t cb, void *data)
 {
        struct config_options opts = {0};
        struct strbuf commondir = STRBUF_INIT;
 {
        struct config_options opts = {0};
        struct strbuf commondir = STRBUF_INIT;
@@ -2175,9 +2184,9 @@ void read_early_config(config_fn_t cb, void *data)
 
        opts.respect_includes = 1;
 
 
        opts.respect_includes = 1;
 
-       if (have_git_dir()) {
-               opts.commondir = get_git_common_dir();
-               opts.git_dir = get_git_dir();
+       if (repo && repo->gitdir) {
+               opts.commondir = repo_get_common_dir(repo);
+               opts.git_dir = repo_get_git_dir(repo);
        /*
         * When setup_git_directory() was not yet asked to discover the
         * GIT_DIR, we ask discover_git_directory() to figure out whether there
        /*
         * When setup_git_directory() was not yet asked to discover the
         * GIT_DIR, we ask discover_git_directory() to figure out whether there
@@ -2197,10 +2206,6 @@ void read_early_config(config_fn_t cb, void *data)
        strbuf_release(&gitdir);
 }
 
        strbuf_release(&gitdir);
 }
 
-/*
- * Read config but only enumerate system and global settings.
- * Omit any repo-local, worktree-local, or command-line settings.
- */
 void read_very_early_config(config_fn_t cb, void *data)
 {
        struct config_options opts = { 0 };
 void read_very_early_config(config_fn_t cb, void *data)
 {
        struct config_options opts = { 0 };
@@ -2404,7 +2409,7 @@ int git_configset_get_string(struct config_set *set, const char *key, char **des
 {
        const char *value;
        if (!git_configset_get_value(set, key, &value, NULL))
 {
        const char *value;
        if (!git_configset_get_value(set, key, &value, NULL))
-               return git_config_string((const char **)dest, key, value);
+               return git_config_string(dest, key, value);
        else
                return 1;
 }
        else
                return 1;
 }
@@ -2482,7 +2487,7 @@ int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *d
                return 1;
 }
 
                return 1;
 }
 
-int git_configset_get_pathname(struct config_set *set, const char *key, const char **dest)
+int git_configset_get_pathname(struct config_set *set, const char *key, char **dest)
 {
        const char *value;
        if (!git_configset_get_value(set, key, &value, NULL))
 {
        const char *value;
        if (!git_configset_get_value(set, key, &value, NULL))
@@ -2529,7 +2534,7 @@ static void git_config_check_init(struct repository *repo)
        repo_read_config(repo);
 }
 
        repo_read_config(repo);
 }
 
-static void repo_config_clear(struct repository *repo)
+void repo_config_clear(struct repository *repo)
 {
        if (!repo->config || !repo->config->hash_initialized)
                return;
 {
        if (!repo->config || !repo->config->hash_initialized)
                return;
@@ -2576,7 +2581,7 @@ int repo_config_get_string(struct repository *repo,
        git_config_check_init(repo);
        ret = git_configset_get_string(repo->config, key, dest);
        if (ret < 0)
        git_config_check_init(repo);
        ret = git_configset_get_string(repo->config, key, dest);
        if (ret < 0)
-               git_die_config(key, NULL);
+               git_die_config(repo, key, NULL);
        return ret;
 }
 
        return ret;
 }
 
@@ -2587,7 +2592,7 @@ int repo_config_get_string_tmp(struct repository *repo,
        git_config_check_init(repo);
        ret = git_configset_get_string_tmp(repo->config, key, dest);
        if (ret < 0)
        git_config_check_init(repo);
        ret = git_configset_get_string_tmp(repo->config, key, dest);
        if (ret < 0)
-               git_die_config(key, NULL);
+               git_die_config(repo, key, NULL);
        return ret;
 }
 
        return ret;
 }
 
@@ -2627,13 +2632,13 @@ int repo_config_get_maybe_bool(struct repository *repo,
 }
 
 int repo_config_get_pathname(struct repository *repo,
 }
 
 int repo_config_get_pathname(struct repository *repo,
-                            const char *key, const char **dest)
+                            const char *key, char **dest)
 {
        int ret;
        git_config_check_init(repo);
        ret = git_configset_get_pathname(repo->config, key, dest);
        if (ret < 0)
 {
        int ret;
        git_config_check_init(repo);
        ret = git_configset_get_pathname(repo->config, key, dest);
        if (ret < 0)
-               git_die_config(key, NULL);
+               git_die_config(repo, key, NULL);
        return ret;
 }
 
        return ret;
 }
 
@@ -2659,98 +2664,28 @@ void git_protected_config(config_fn_t fn, void *data)
        configset_iter(&protected_config, fn, data);
 }
 
        configset_iter(&protected_config, fn, data);
 }
 
-/* Functions used historically to read configuration from 'the_repository' */
-void git_config(config_fn_t fn, void *data)
-{
-       repo_config(the_repository, fn, data);
-}
-
-void git_config_clear(void)
-{
-       repo_config_clear(the_repository);
-}
-
-int git_config_get(const char *key)
-{
-       return repo_config_get(the_repository, key);
-}
-
-int git_config_get_value(const char *key, const char **value)
-{
-       return repo_config_get_value(the_repository, key, value);
-}
-
-int git_config_get_value_multi(const char *key, const struct string_list **dest)
-{
-       return repo_config_get_value_multi(the_repository, key, dest);
-}
-
-int git_config_get_string_multi(const char *key,
-                               const struct string_list **dest)
-{
-       return repo_config_get_string_multi(the_repository, key, dest);
-}
-
-int git_config_get_string(const char *key, char **dest)
-{
-       return repo_config_get_string(the_repository, key, dest);
-}
-
-int git_config_get_string_tmp(const char *key, const char **dest)
-{
-       return repo_config_get_string_tmp(the_repository, key, dest);
-}
-
-int git_config_get_int(const char *key, int *dest)
-{
-       return repo_config_get_int(the_repository, key, dest);
-}
-
-int git_config_get_ulong(const char *key, unsigned long *dest)
-{
-       return repo_config_get_ulong(the_repository, key, dest);
-}
-
-int git_config_get_bool(const char *key, int *dest)
-{
-       return repo_config_get_bool(the_repository, key, dest);
-}
-
-int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)
+int repo_config_get_expiry(struct repository *r, const char *key, char **output)
 {
 {
-       return repo_config_get_bool_or_int(the_repository, key, is_bool, dest);
-}
+       int ret = repo_config_get_string(r, key, output);
 
 
-int git_config_get_maybe_bool(const char *key, int *dest)
-{
-       return repo_config_get_maybe_bool(the_repository, key, dest);
-}
-
-int git_config_get_pathname(const char *key, const char **dest)
-{
-       return repo_config_get_pathname(the_repository, key, dest);
-}
-
-int git_config_get_expiry(const char *key, const char **output)
-{
-       int ret = git_config_get_string(key, (char **)output);
        if (ret)
                return ret;
        if (strcmp(*output, "now")) {
                timestamp_t now = approxidate("now");
                if (approxidate(*output) >= now)
        if (ret)
                return ret;
        if (strcmp(*output, "now")) {
                timestamp_t now = approxidate("now");
                if (approxidate(*output) >= now)
-                       git_die_config(key, _("Invalid %s: '%s'"), key, *output);
+                       git_die_config(r, key, _("Invalid %s: '%s'"), key, *output);
        }
        return ret;
 }
 
        }
        return ret;
 }
 
-int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
+int repo_config_get_expiry_in_days(struct repository *r, const char *key,
+                                  timestamp_t *expiry, timestamp_t now)
 {
        const char *expiry_string;
        intmax_t days;
        timestamp_t when;
 
 {
        const char *expiry_string;
        intmax_t days;
        timestamp_t when;
 
-       if (git_config_get_string_tmp(key, &expiry_string))
+       if (repo_config_get_string_tmp(r, key, &expiry_string))
                return 1; /* no such thing */
 
        if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
                return 1; /* no such thing */
 
        if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
@@ -2766,21 +2701,21 @@ int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestam
        return -1; /* thing exists but cannot be parsed */
 }
 
        return -1; /* thing exists but cannot be parsed */
 }
 
-int git_config_get_split_index(void)
+int repo_config_get_split_index(struct repository *r)
 {
        int val;
 
 {
        int val;
 
-       if (!git_config_get_maybe_bool("core.splitindex", &val))
+       if (!repo_config_get_maybe_bool(r, "core.splitindex", &val))
                return val;
 
        return -1; /* default value */
 }
 
                return val;
 
        return -1; /* default value */
 }
 
-int git_config_get_max_percent_split_change(void)
+int repo_config_get_max_percent_split_change(struct repository *r)
 {
        int val = -1;
 
 {
        int val = -1;
 
-       if (!git_config_get_int("splitindex.maxpercentchange", &val)) {
+       if (!repo_config_get_int(r, "splitindex.maxpercentchange", &val)) {
                if (0 <= val && val <= 100)
                        return val;
 
                if (0 <= val && val <= 100)
                        return val;
 
@@ -2791,7 +2726,7 @@ int git_config_get_max_percent_split_change(void)
        return -1; /* default value */
 }
 
        return -1; /* default value */
 }
 
-int git_config_get_index_threads(int *dest)
+int repo_config_get_index_threads(struct repository *r, int *dest)
 {
        int is_bool, val;
 
 {
        int is_bool, val;
 
@@ -2801,7 +2736,7 @@ int git_config_get_index_threads(int *dest)
                return 0;
        }
 
                return 0;
        }
 
-       if (!git_config_get_bool_or_int("index.threads", &is_bool, &val)) {
+       if (!repo_config_get_bool_or_int(r, "index.threads", &is_bool, &val)) {
                if (is_bool)
                        *dest = val ? 0 : 1;
                else
                if (is_bool)
                        *dest = val ? 0 : 1;
                else
@@ -2822,8 +2757,7 @@ void git_die_config_linenr(const char *key, const char *filename, int linenr)
                    key, filename, linenr);
 }
 
                    key, filename, linenr);
 }
 
-NORETURN __attribute__((format(printf, 2, 3)))
-void git_die_config(const char *key, const char *err, ...)
+void git_die_config(struct repository *r, const char *key, const char *err, ...)
 {
        const struct string_list *values;
        struct key_value_info *kv_info;
 {
        const struct string_list *values;
        struct key_value_info *kv_info;
@@ -2835,7 +2769,7 @@ void git_die_config(const char *key, const char *err, ...)
                error_fn(err, params);
                va_end(params);
        }
                error_fn(err, params);
                va_end(params);
        }
-       if (git_config_get_value_multi(key, &values))
+       if (repo_config_get_value_multi(r, key, &values))
                BUG("for key '%s' we must have a value to report on", key);
        kv_info = values->items[values->nr - 1].util;
        git_die_config_linenr(key, kv_info->filename, kv_info->linenr);
                BUG("for key '%s' we must have a value to report on", key);
        kv_info = values->items[values->nr - 1].util;
        git_die_config_linenr(key, kv_info->filename, kv_info->linenr);
@@ -2880,7 +2814,7 @@ static int matches(const char *key, const char *value,
 {
        if (strcmp(key, store->key))
                return 0; /* not ours */
 {
        if (strcmp(key, store->key))
                return 0; /* not ours */
-       if (store->fixed_value)
+       if (store->fixed_value && value)
                return !strcmp(store->fixed_value, value);
        if (!store->value_pattern)
                return 1; /* always matches */
                return !strcmp(store->fixed_value, value);
        if (!store->value_pattern)
                return 1; /* always matches */
@@ -3144,21 +3078,21 @@ static void maybe_remove_section(struct config_store_data *store,
                *end_offset = store->parsed[store->parsed_nr - 1].end;
 }
 
                *end_offset = store->parsed[store->parsed_nr - 1].end;
 }
 
-int git_config_set_in_file_gently(const char *config_filename,
-                                 const char *key, const char *comment, const char *value)
+int repo_config_set_in_file_gently(struct repository *r, const char *config_filename,
+                                  const char *key, const char *comment, const char *value)
 {
 {
-       return git_config_set_multivar_in_file_gently(config_filename, key, value, NULL, comment, 0);
+       return repo_config_set_multivar_in_file_gently(r, config_filename, key, value, NULL, comment, 0);
 }
 
 }
 
-void git_config_set_in_file(const char *config_filename,
-                           const char *key, const char *value)
+void repo_config_set_in_file(struct repository *r, const char *config_filename,
+                            const char *key, const char *value)
 {
 {
-       git_config_set_multivar_in_file(config_filename, key, value, NULL, 0);
+       repo_config_set_multivar_in_file(r, config_filename, key, value, NULL, 0);
 }
 
 }
 
-int git_config_set_gently(const char *key, const char *value)
+int repo_config_set_gently(struct repository *r, const char *key, const char *value)
 {
 {
-       return git_config_set_multivar_gently(key, value, NULL, 0);
+       return repo_config_set_multivar_gently(r, key, value, NULL, 0);
 }
 
 int repo_config_set_worktree_gently(struct repository *r,
 }
 
 int repo_config_set_worktree_gently(struct repository *r,
@@ -3167,29 +3101,25 @@ int repo_config_set_worktree_gently(struct repository *r,
        /* Only use worktree-specific config if it is already enabled. */
        if (r->repository_format_worktree_config) {
                char *file = repo_git_path(r, "config.worktree");
        /* Only use worktree-specific config if it is already enabled. */
        if (r->repository_format_worktree_config) {
                char *file = repo_git_path(r, "config.worktree");
-               int ret = git_config_set_multivar_in_file_gently(
-                                       file, key, value, NULL, NULL, 0);
+               int ret = repo_config_set_multivar_in_file_gently(
+                                       r, file, key, value, NULL, NULL, 0);
                free(file);
                return ret;
        }
        return repo_config_set_multivar_gently(r, key, value, NULL, 0);
 }
 
                free(file);
                return ret;
        }
        return repo_config_set_multivar_gently(r, key, value, NULL, 0);
 }
 
-void git_config_set(const char *key, const char *value)
+void repo_config_set(struct repository *r, const char *key, const char *value)
 {
 {
-       git_config_set_multivar(key, value, NULL, 0);
+       repo_config_set_multivar(r, key, value, NULL, 0);
 
        trace2_cmd_set_config(key, value);
 }
 
 
        trace2_cmd_set_config(key, value);
 }
 
-/*
- * The ownership rule is that the caller will own the string
- * if it receives a piece of memory different from what it passed
- * as the parameter.
- */
-const char *git_config_prepare_comment_string(const char *comment)
+char *git_config_prepare_comment_string(const char *comment)
 {
        size_t leading_blanks;
 {
        size_t leading_blanks;
+       char *prepared;
 
        if (!comment)
                return NULL;
 
        if (!comment)
                return NULL;
@@ -3210,13 +3140,13 @@ const char *git_config_prepare_comment_string(const char *comment)
 
        leading_blanks = strspn(comment, " \t");
        if (leading_blanks && comment[leading_blanks] == '#')
 
        leading_blanks = strspn(comment, " \t");
        if (leading_blanks && comment[leading_blanks] == '#')
-               ; /* use it as-is */
+               prepared = xstrdup(comment); /* use it as-is */
        else if (comment[0] == '#')
        else if (comment[0] == '#')
-               comment = xstrfmt(" %s", comment);
+               prepared = xstrfmt(" %s", comment);
        else
        else
-               comment = xstrfmt(" # %s", comment);
+               prepared = xstrfmt(" # %s", comment);
 
 
-       return comment;
+       return prepared;
 }
 
 static void validate_comment_string(const char *comment)
 }
 
 static void validate_comment_string(const char *comment)
@@ -3263,11 +3193,12 @@ static void validate_comment_string(const char *comment)
  * - the config file is removed and the lock file rename()d to it.
  *
  */
  * - the config file is removed and the lock file rename()d to it.
  *
  */
-int git_config_set_multivar_in_file_gently(const char *config_filename,
-                                          const char *key, const char *value,
-                                          const char *value_pattern,
-                                          const char *comment,
-                                          unsigned flags)
+int repo_config_set_multivar_in_file_gently(struct repository *r,
+                                           const char *config_filename,
+                                           const char *key, const char *value,
+                                           const char *value_pattern,
+                                           const char *comment,
+                                           unsigned flags)
 {
        int fd = -1, in_fd = -1;
        int ret;
 {
        int fd = -1, in_fd = -1;
        int ret;
@@ -3287,7 +3218,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
        store.multi_replace = (flags & CONFIG_FLAGS_MULTI_REPLACE) != 0;
 
        if (!config_filename)
        store.multi_replace = (flags & CONFIG_FLAGS_MULTI_REPLACE) != 0;
 
        if (!config_filename)
-               config_filename = filename_buf = git_pathdup("config");
+               config_filename = filename_buf = repo_git_path(r, "config");
 
        /*
         * The lock serves a purpose in addition to locking: the new
 
        /*
         * The lock serves a purpose in addition to locking: the new
@@ -3496,7 +3427,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
        ret = 0;
 
        /* Invalidate the config cache */
        ret = 0;
 
        /* Invalidate the config cache */
-       git_config_clear();
+       repo_config_clear(r);
 
 out_free:
        rollback_lock_file(&lock);
 
 out_free:
        rollback_lock_file(&lock);
@@ -3513,12 +3444,13 @@ write_err_out:
        goto out_free;
 }
 
        goto out_free;
 }
 
-void git_config_set_multivar_in_file(const char *config_filename,
-                                    const char *key, const char *value,
-                                    const char *value_pattern, unsigned flags)
+void repo_config_set_multivar_in_file(struct repository *r,
+                                     const char *config_filename,
+                                     const char *key, const char *value,
+                                     const char *value_pattern, unsigned flags)
 {
 {
-       if (!git_config_set_multivar_in_file_gently(config_filename, key, value,
-                                                   value_pattern, NULL, flags))
+       if (!repo_config_set_multivar_in_file_gently(r, config_filename, key, value,
+                                                    value_pattern, NULL, flags))
                return;
        if (value)
                die(_("could not set '%s' to '%s'"), key, value);
                return;
        if (value)
                die(_("could not set '%s' to '%s'"), key, value);
@@ -3526,32 +3458,27 @@ void git_config_set_multivar_in_file(const char *config_filename,
                die(_("could not unset '%s'"), key);
 }
 
                die(_("could not unset '%s'"), key);
 }
 
-int git_config_set_multivar_gently(const char *key, const char *value,
-                                  const char *value_pattern, unsigned flags)
-{
-       return repo_config_set_multivar_gently(the_repository, key, value,
-                                              value_pattern, flags);
-}
-
 int repo_config_set_multivar_gently(struct repository *r, const char *key,
                                    const char *value,
                                    const char *value_pattern, unsigned flags)
 {
        char *file = repo_git_path(r, "config");
 int repo_config_set_multivar_gently(struct repository *r, const char *key,
                                    const char *value,
                                    const char *value_pattern, unsigned flags)
 {
        char *file = repo_git_path(r, "config");
-       int res = git_config_set_multivar_in_file_gently(file,
-                                                        key, value,
-                                                        value_pattern,
-                                                        NULL, flags);
+       int res = repo_config_set_multivar_in_file_gently(r, file,
+                                                         key, value,
+                                                         value_pattern,
+                                                         NULL, flags);
        free(file);
        return res;
 }
 
        free(file);
        return res;
 }
 
-void git_config_set_multivar(const char *key, const char *value,
-                            const char *value_pattern, unsigned flags)
+void repo_config_set_multivar(struct repository *r,
+                             const char *key, const char *value,
+                             const char *value_pattern, unsigned flags)
 {
 {
-       git_config_set_multivar_in_file(git_path("config"),
-                                       key, value, value_pattern,
-                                       flags);
+       char *file = repo_git_path(r, "config");
+       repo_config_set_multivar_in_file(r, file, key, value,
+                                        value_pattern, flags);
+       free(file);
 }
 
 static size_t section_name_match (const char *buf, const char *name)
 }
 
 static size_t section_name_match (const char *buf, const char *name)
@@ -3613,9 +3540,11 @@ static int section_name_is_ok(const char *name)
 #define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)
 
 /* if new_name == NULL, the section is removed instead */
 #define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)
 
 /* if new_name == NULL, the section is removed instead */
-static int git_config_copy_or_rename_section_in_file(const char *config_filename,
-                                     const char *old_name,
-                                     const char *new_name, int copy)
+static int repo_config_copy_or_rename_section_in_file(
+       struct repository *r,
+       const char *config_filename,
+       const char *old_name,
+       const char *new_name, int copy)
 {
        int ret = 0, remove = 0;
        char *filename_buf = NULL;
 {
        int ret = 0, remove = 0;
        char *filename_buf = NULL;
@@ -3636,7 +3565,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
        }
 
        if (!config_filename)
        }
 
        if (!config_filename)
-               config_filename = filename_buf = git_pathdup("config");
+               config_filename = filename_buf = repo_git_path(r, "config");
 
        out_fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (out_fd < 0) {
 
        out_fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (out_fd < 0) {
@@ -3779,28 +3708,28 @@ out_no_rollback:
        return ret;
 }
 
        return ret;
 }
 
-int git_config_rename_section_in_file(const char *config_filename,
-                                     const char *old_name, const char *new_name)
+int repo_config_rename_section_in_file(struct repository *r, const char *config_filename,
+                                      const char *old_name, const char *new_name)
 {
 {
-       return git_config_copy_or_rename_section_in_file(config_filename,
+       return repo_config_copy_or_rename_section_in_file(r, config_filename,
                                         old_name, new_name, 0);
 }
 
                                         old_name, new_name, 0);
 }
 
-int git_config_rename_section(const char *old_name, const char *new_name)
+int repo_config_rename_section(struct repository *r, const char *old_name, const char *new_name)
 {
 {
-       return git_config_rename_section_in_file(NULL, old_name, new_name);
+       return repo_config_rename_section_in_file(r, NULL, old_name, new_name);
 }
 
 }
 
-int git_config_copy_section_in_file(const char *config_filename,
-                                     const char *old_name, const char *new_name)
+int repo_config_copy_section_in_file(struct repository *r, const char *config_filename,
+                                    const char *old_name, const char *new_name)
 {
 {
-       return git_config_copy_or_rename_section_in_file(config_filename,
+       return repo_config_copy_or_rename_section_in_file(r, config_filename,
                                         old_name, new_name, 1);
 }
 
                                         old_name, new_name, 1);
 }
 
-int git_config_copy_section(const char *old_name, const char *new_name)
+int repo_config_copy_section(struct repository *r, const char *old_name, const char *new_name)
 {
 {
-       return git_config_copy_section_in_file(NULL, old_name, new_name);
+       return repo_config_copy_section_in_file(r, NULL, old_name, new_name);
 }
 
 /*
 }
 
 /*