Show changes to 3 files +70 −63
repository.c, setup.c, setup.h
diff --git a/repository.c b/repository.c
index db57b8308b..58a13f7c4f 100644
--- a/repository.c
+++ b/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;
}
diff --git a/setup.c b/setup.c
index 252b443117..c5015923f1 100644
--- a/setup.c
+++ b/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);
diff --git a/setup.h b/setup.h
index 9409326fe4..5ed92f53fa 100644
--- a/setup.h
+++ b/setup.h
@@ -221,6 +221,15 @@ 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 otherwise.
+ */
+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)