mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-11 08:30:32 -05:00
setup: deduplicate logic to apply repository format
After having discovered the repository format we then apply it to the repository so that it knows to use the proper repository extensions. The logic to apply the format is duplicated across three callsites, which makes it rather painfull to add new extensions. Introduce a new function `apply_repository_format()` that takes a repo and applies a given format to it and adapt all callsites to use it. This function is also the new caller of `verify_repository_format()` so that we can ensure that we never apply an invalid repository format. The verification we have in `read_and_verify_repository_format()` is thus redundant now and dropped. Rename `read_and_verify_repository_format()` accordingly. While at it, also rename `check_repository_format()` to clarify that it doesn't only _check_ the format, but that it also applies it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
452ad8db6d
commit
3d884b0b56
31
repository.c
31
repository.c
@@ -262,8 +262,8 @@ void repo_set_worktree(struct repository *repo, const char *path)
|
||||
trace2_def_repo(repo);
|
||||
}
|
||||
|
||||
static int read_and_verify_repository_format(struct repository_format *format,
|
||||
const char *commondir)
|
||||
static int read_repository_format_from_commondir(struct repository_format *format,
|
||||
const char *commondir)
|
||||
{
|
||||
int ret = 0;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
@@ -272,11 +272,6 @@ static int read_and_verify_repository_format(struct repository_format *format,
|
||||
read_repository_format(format, sb.buf);
|
||||
strbuf_reset(&sb);
|
||||
|
||||
if (verify_repository_format(format, &sb) < 0) {
|
||||
warning("%s", sb.buf);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
strbuf_release(&sb);
|
||||
return ret;
|
||||
}
|
||||
@@ -290,6 +285,8 @@ int repo_init(struct repository *repo,
|
||||
const char *worktree)
|
||||
{
|
||||
struct repository_format format = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
memset(repo, 0, sizeof(*repo));
|
||||
|
||||
initialize_repository(repo);
|
||||
@@ -297,21 +294,13 @@ int repo_init(struct repository *repo,
|
||||
if (repo_init_gitdir(repo, gitdir))
|
||||
goto error;
|
||||
|
||||
if (read_and_verify_repository_format(&format, repo->commondir))
|
||||
if (read_repository_format_from_commondir(&format, repo->commondir))
|
||||
goto error;
|
||||
|
||||
repo_set_hash_algo(repo, format.hash_algo);
|
||||
repo_set_compat_hash_algo(repo, format.compat_hash_algo);
|
||||
repo_set_ref_storage_format(repo, format.ref_storage_format,
|
||||
format.ref_storage_payload);
|
||||
repo->repository_format_worktree_config = format.worktree_config;
|
||||
repo->repository_format_relative_worktrees = format.relative_worktrees;
|
||||
repo->repository_format_precious_objects = format.precious_objects;
|
||||
repo->repository_format_submodule_path_cfg = format.submodule_path_cfg;
|
||||
|
||||
/* take ownership of format.partial_clone */
|
||||
repo->repository_format_partial_clone = format.partial_clone;
|
||||
format.partial_clone = NULL;
|
||||
if (apply_repository_format(repo, &format, &err) < 0) {
|
||||
warning("%s", err.buf);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (worktree)
|
||||
repo_set_worktree(repo, worktree);
|
||||
@@ -320,10 +309,12 @@ int repo_init(struct repository *repo,
|
||||
repo_read_loose_object_map(repo);
|
||||
|
||||
clear_repository_format(&format);
|
||||
strbuf_release(&err);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
clear_repository_format(&format);
|
||||
strbuf_release(&err);
|
||||
repo_clear(repo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
93
setup.c
93
setup.c
@@ -750,8 +750,7 @@ static int check_repo_format(const char *var, const char *value,
|
||||
return read_worktree_config(var, value, ctx, vdata);
|
||||
}
|
||||
|
||||
static int check_repository_format_gently(struct repository *repo,
|
||||
const char *gitdir,
|
||||
static int check_repository_format_gently(const char *gitdir,
|
||||
struct repository_format *candidate,
|
||||
int *nongit_ok)
|
||||
{
|
||||
@@ -765,7 +764,7 @@ static int check_repository_format_gently(struct repository *repo,
|
||||
strbuf_release(&sb);
|
||||
|
||||
/*
|
||||
* For historical use of check_repository_format() in git-init,
|
||||
* For historical use of check_and_apply_repository_format() in git-init,
|
||||
* we treat a missing config as a silent "ok", even when nongit_ok
|
||||
* is unset.
|
||||
*/
|
||||
@@ -782,8 +781,6 @@ static int check_repository_format_gently(struct repository *repo,
|
||||
die("%s", err.buf);
|
||||
}
|
||||
|
||||
repo->repository_format_precious_objects = candidate->precious_objects;
|
||||
|
||||
string_list_clear(&candidate->unknown_extensions, 0);
|
||||
string_list_clear(&candidate->v1_only_extensions, 0);
|
||||
|
||||
@@ -1140,7 +1137,7 @@ static const char *setup_explicit_git_dir(struct repository *repo,
|
||||
die(_("not a git repository: '%s'"), gitdirenv);
|
||||
}
|
||||
|
||||
if (check_repository_format_gently(repo, gitdirenv, repo_fmt, nongit_ok)) {
|
||||
if (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {
|
||||
free(gitfile);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1217,7 +1214,7 @@ static const char *setup_discovered_git_dir(struct repository *repo,
|
||||
struct repository_format *repo_fmt,
|
||||
int *nongit_ok)
|
||||
{
|
||||
if (check_repository_format_gently(repo, gitdir, repo_fmt, nongit_ok))
|
||||
if (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))
|
||||
return NULL;
|
||||
|
||||
/* --work-tree is set without --git-dir; use discovered one */
|
||||
@@ -1265,7 +1262,7 @@ static const char *setup_bare_git_dir(struct repository *repo,
|
||||
{
|
||||
int root_len;
|
||||
|
||||
if (check_repository_format_gently(repo, ".", repo_fmt, nongit_ok))
|
||||
if (check_repository_format_gently(".", repo_fmt, nongit_ok))
|
||||
return NULL;
|
||||
|
||||
setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
|
||||
@@ -1757,6 +1754,32 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
|
||||
return result;
|
||||
}
|
||||
|
||||
int apply_repository_format(struct repository *repo,
|
||||
const struct repository_format *format,
|
||||
struct strbuf *err)
|
||||
{
|
||||
if (verify_repository_format(format, err) < 0)
|
||||
return -1;
|
||||
|
||||
repo_set_hash_algo(repo, format->hash_algo);
|
||||
repo_set_compat_hash_algo(repo, format->compat_hash_algo);
|
||||
repo_set_ref_storage_format(repo,
|
||||
format->ref_storage_format,
|
||||
format->ref_storage_payload);
|
||||
repo->repository_format_worktree_config =
|
||||
format->worktree_config;
|
||||
repo->repository_format_submodule_path_cfg =
|
||||
format->submodule_path_cfg;
|
||||
repo->repository_format_relative_worktrees =
|
||||
format->relative_worktrees;
|
||||
repo->repository_format_partial_clone =
|
||||
xstrdup_or_null(format->partial_clone);
|
||||
repo->repository_format_precious_objects =
|
||||
format->precious_objects;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the repository format version in the path found in repo_get_git_dir(repo),
|
||||
* and die if it is a version we don't understand. Generally one would
|
||||
@@ -1765,26 +1788,20 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
|
||||
*
|
||||
* If successful and fmt is not NULL, fill fmt with data.
|
||||
*/
|
||||
static void check_repository_format(struct repository *repo, struct repository_format *fmt)
|
||||
static void check_and_apply_repository_format(struct repository *repo,
|
||||
struct repository_format *fmt)
|
||||
{
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
if (!fmt)
|
||||
fmt = &repo_fmt;
|
||||
check_repository_format_gently(repo, repo_get_git_dir(repo), fmt, NULL);
|
||||
|
||||
check_repository_format_gently(repo_get_git_dir(repo), fmt, NULL);
|
||||
if (apply_repository_format(repo, fmt, &err) < 0)
|
||||
die("%s", err.buf);
|
||||
startup_info->have_repository = 1;
|
||||
repo_set_hash_algo(repo, fmt->hash_algo);
|
||||
repo_set_compat_hash_algo(repo, fmt->compat_hash_algo);
|
||||
repo_set_ref_storage_format(repo,
|
||||
fmt->ref_storage_format,
|
||||
fmt->ref_storage_payload);
|
||||
repo->repository_format_worktree_config =
|
||||
fmt->worktree_config;
|
||||
repo->repository_format_submodule_path_cfg =
|
||||
fmt->submodule_path_cfg;
|
||||
repo->repository_format_relative_worktrees =
|
||||
fmt->relative_worktrees;
|
||||
repo->repository_format_partial_clone =
|
||||
xstrdup_or_null(fmt->partial_clone);
|
||||
|
||||
clear_repository_format(&repo_fmt);
|
||||
}
|
||||
|
||||
@@ -1862,7 +1879,7 @@ const char *enter_repo(struct repository *repo, const char *path, unsigned flags
|
||||
|
||||
if (is_git_directory(".")) {
|
||||
set_git_dir(repo, ".", 0);
|
||||
check_repository_format(repo, NULL);
|
||||
check_and_apply_repository_format(repo, NULL);
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -2020,25 +2037,15 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
|
||||
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
|
||||
setup_git_env_internal(repo, gitdir, false);
|
||||
}
|
||||
|
||||
if (startup_info->have_repository) {
|
||||
repo_set_hash_algo(repo, repo_fmt.hash_algo);
|
||||
repo_set_compat_hash_algo(repo,
|
||||
repo_fmt.compat_hash_algo);
|
||||
repo_set_ref_storage_format(repo,
|
||||
repo_fmt.ref_storage_format,
|
||||
repo_fmt.ref_storage_payload);
|
||||
repo->repository_format_worktree_config =
|
||||
repo_fmt.worktree_config;
|
||||
repo->repository_format_relative_worktrees =
|
||||
repo_fmt.relative_worktrees;
|
||||
repo->repository_format_submodule_path_cfg =
|
||||
repo_fmt.submodule_path_cfg;
|
||||
/* take ownership of repo_fmt.partial_clone */
|
||||
repo->repository_format_partial_clone =
|
||||
repo_fmt.partial_clone;
|
||||
repo_fmt.partial_clone = NULL;
|
||||
repo->repository_format_precious_objects =
|
||||
repo_fmt.precious_objects;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
if (apply_repository_format(repo, &repo_fmt, &err) < 0)
|
||||
die("%s", err.buf);
|
||||
|
||||
clear_repository_format(&repo_fmt);
|
||||
strbuf_release(&err);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -2814,7 +2821,7 @@ int init_db(struct repository *repo,
|
||||
* 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, &repo_fmt);
|
||||
check_and_apply_repository_format(repo, &repo_fmt);
|
||||
|
||||
repository_format_configure(repo, &repo_fmt, hash, ref_storage_format);
|
||||
|
||||
|
||||
10
setup.h
10
setup.h
@@ -221,6 +221,16 @@ void clear_repository_format(struct repository_format *format);
|
||||
int verify_repository_format(const struct repository_format *format,
|
||||
struct strbuf *err);
|
||||
|
||||
/*
|
||||
* Apply the given repository format to the repo. This initializes extensions
|
||||
* and basic data structures required for normal operation. Returns 0 on
|
||||
* success, a negative error code when the format is not valid as determined by
|
||||
* `verify_repository_format()`.
|
||||
*/
|
||||
int apply_repository_format(struct repository *repo,
|
||||
const struct repository_format *format,
|
||||
struct strbuf *err);
|
||||
|
||||
const char *get_template_dir(const char *option_template);
|
||||
|
||||
#define INIT_DB_QUIET (1 << 0)
|
||||
|
||||
Reference in New Issue
Block a user