diff options
author | Junio C Hamano <gitster@pobox.com> | 2024-08-23 18:02:35 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-08-23 18:02:36 +0200 |
commit | 2cf9c2206cd9b0f47ef60dfe84a9f16483f7ab94 (patch) | |
tree | 3d946b38a28241cb28b26ae3bfb6b59824314ae1 /setup.c | |
parent | Merge branch 'cp/unit-test-reftable-readwrite' (diff) | |
parent | setup: make ref storage format configurable via config (diff) | |
download | git-2cf9c2206cd9b0f47ef60dfe84a9f16483f7ab94.tar.xz git-2cf9c2206cd9b0f47ef60dfe84a9f16483f7ab94.zip |
Merge branch 'ps/hash-and-ref-format-from-config'
The default object hash and ref backend format used to be settable
only with explicit command line option to "git init" and
environment variables, but now they can be configured in the user's
global and system wide configuration.
* ps/hash-and-ref-format-from-config:
setup: make ref storage format configurable via config
setup: make object format configurable via config
setup: merge configuration of repository formats
t0001: delete repositories when object format tests finish
t0001: exercise initialization with ref formats more thoroughly
Diffstat (limited to 'setup.c')
-rw-r--r-- | setup.c | 101 |
1 files changed, 74 insertions, 27 deletions
@@ -2320,14 +2320,67 @@ static void separate_git_dir(const char *git_dir, const char *git_link) write_file(git_link, "gitdir: %s", git_dir); } -static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash) +struct default_format_config { + int hash; + enum ref_storage_format ref_format; +}; + +static int read_default_format_config(const char *key, const char *value, + const struct config_context *ctx UNUSED, + void *payload) { - const char *env = getenv(GIT_DEFAULT_HASH_ENVIRONMENT); + struct default_format_config *cfg = payload; + char *str = NULL; + int ret; + + if (!strcmp(key, "init.defaultobjectformat")) { + ret = git_config_string(&str, key, value); + if (ret) + goto out; + cfg->hash = hash_algo_by_name(str); + if (cfg->hash == GIT_HASH_UNKNOWN) + warning(_("unknown hash algorithm '%s'"), str); + goto out; + } + + if (!strcmp(key, "init.defaultrefformat")) { + ret = git_config_string(&str, key, value); + if (ret) + goto out; + cfg->ref_format = ref_storage_format_by_name(str); + if (cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN) + warning(_("unknown ref storage format '%s'"), str); + goto out; + } + + ret = 0; +out: + free(str); + return ret; +} + +static void repository_format_configure(struct repository_format *repo_fmt, + int hash, enum ref_storage_format ref_format) +{ + struct default_format_config cfg = { + .hash = GIT_HASH_UNKNOWN, + .ref_format = REF_STORAGE_FORMAT_UNKNOWN, + }; + struct config_options opts = { + .respect_includes = 1, + .ignore_repo = 1, + .ignore_worktree = 1, + }; + const char *env; + + config_with_options(read_default_format_config, &cfg, NULL, NULL, &opts); + /* * If we already have an initialized repo, don't allow the user to * specify a different algorithm, as that could cause corruption. * Otherwise, if the user has specified one on the command line, use it. */ + env = getenv(GIT_DEFAULT_HASH_ENVIRONMENT); if (repo_fmt->version >= 0 && hash != GIT_HASH_UNKNOWN && hash != repo_fmt->hash_algo) die(_("attempt to reinitialize repository with different hash")); else if (hash != GIT_HASH_UNKNOWN) @@ -2337,26 +2390,27 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash if (env_algo == GIT_HASH_UNKNOWN) die(_("unknown hash algorithm '%s'"), env); repo_fmt->hash_algo = env_algo; + } else if (cfg.hash != GIT_HASH_UNKNOWN) { + repo_fmt->hash_algo = cfg.hash; } -} - -static void validate_ref_storage_format(struct repository_format *repo_fmt, - enum ref_storage_format format) -{ - const char *name = getenv("GIT_DEFAULT_REF_FORMAT"); + repo_set_hash_algo(the_repository, repo_fmt->hash_algo); + env = getenv("GIT_DEFAULT_REF_FORMAT"); if (repo_fmt->version >= 0 && - format != REF_STORAGE_FORMAT_UNKNOWN && - format != repo_fmt->ref_storage_format) { + ref_format != REF_STORAGE_FORMAT_UNKNOWN && + ref_format != repo_fmt->ref_storage_format) { die(_("attempt to reinitialize repository with different reference storage format")); - } else if (format != REF_STORAGE_FORMAT_UNKNOWN) { - repo_fmt->ref_storage_format = format; - } else if (name) { - format = ref_storage_format_by_name(name); - if (format == REF_STORAGE_FORMAT_UNKNOWN) - die(_("unknown ref storage format '%s'"), name); - repo_fmt->ref_storage_format = format; + } else if (ref_format != REF_STORAGE_FORMAT_UNKNOWN) { + repo_fmt->ref_storage_format = ref_format; + } else if (env) { + ref_format = ref_storage_format_by_name(env); + if (ref_format == REF_STORAGE_FORMAT_UNKNOWN) + die(_("unknown ref storage format '%s'"), env); + repo_fmt->ref_storage_format = ref_format; + } else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) { + repo_fmt->ref_storage_format = cfg.ref_format; } + repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format); } int init_db(const char *git_dir, const char *real_git_dir, @@ -2389,22 +2443,15 @@ int init_db(const char *git_dir, const char *real_git_dir, } startup_info->have_repository = 1; - /* Check to see if the repository version is right. + /* + * Check to see if the repository version is right. * Note that a newly created repository does not have * config file, so this will not fail. What we are catching * is an attempt to reinitialize new repository with an old tool. */ check_repository_format(&repo_fmt); - validate_hash_algorithm(&repo_fmt, hash); - validate_ref_storage_format(&repo_fmt, ref_storage_format); - - /* - * Now that we have set up both the hash algorithm and the ref storage - * format we can update the repository's settings accordingly. - */ - repo_set_hash_algo(the_repository, repo_fmt.hash_algo); - repo_set_ref_storage_format(the_repository, repo_fmt.ref_storage_format); + repository_format_configure(&repo_fmt, hash, ref_storage_format); /* * Ensure `core.hidedotfiles` is processed. This must happen after we |