repository: allow initialization with a specific refdb type

While we only support initializing repositories with the "files"
reference backend right now, we are in the process of implementing a
second backend with the "reftable" format. And while we already have the
infrastructure to decide which format a repository should use when we
open it, we do not have infrastructure yet to create new repositories
with a different reference format.

Introduce a new field `git_repository_init_options::refdb_type`. If
unset, we'll default to the "files" backend. Otherwise though, if set to
a valid `git_refdb_t`, we will use that new format to initialize the
repostiory.

Note that for now the only thing we do is to write the "refStorage"
extension accordingly. What we explicitly don't yet do is to also handle
the backend-specific logic to initialize the refdb on disk. This will be
implemented in subsequent commits.
This commit is contained in:
Patrick Steinhardt
2025-07-11 12:07:26 +02:00
parent 806a0062fd
commit b1ac78ecb9
3 changed files with 31 additions and 3 deletions

View File

@@ -11,6 +11,7 @@
#include "types.h"
#include "oid.h"
#include "odb.h"
#include "refdb.h"
#include "buffer.h"
#include "commit.h"
@@ -377,6 +378,12 @@ typedef struct {
*/
git_oid_t oid_type;
#endif
/**
* Type of the reference database to use for this repository, or 0 for
* default (currently "files").
*/
git_refdb_t refdb_type;
} git_repository_init_options;
/** Current version for the `git_repository_init_options` structure */

View File

@@ -125,6 +125,16 @@ int git_refdb_ensure_log(git_refdb *refdb, const char *refname);
int git_refdb_lock(void **payload, git_refdb *db, const char *refname);
int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message);
GIT_INLINE(const char *) git_refdb_type_name(git_refdb_t type)
{
switch (type) {
case GIT_REFDB_FILES:
return "files";
default:
return "unknown";
}
}
GIT_INLINE(git_refdb_t) git_refdb_type_fromstr(const char *name)
{
if (strcmp(name, "files") == 0)

View File

@@ -2379,7 +2379,8 @@ static int repo_init_config(
const char *work_dir,
uint32_t flags,
uint32_t mode,
git_oid_t oid_type)
git_oid_t oid_type,
git_refdb_t refdb_type)
{
int error = 0;
git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT;
@@ -2443,6 +2444,11 @@ static int repo_init_config(
SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type));
}
if (refdb_type != GIT_REFDB_FILES) {
SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1);
SET_REPO_CONFIG(string, "extensions.refstorage", git_refdb_type_name(refdb_type));
}
cleanup:
git_str_dispose(&cfg_path);
git_str_dispose(&worktree_path);
@@ -2926,6 +2932,7 @@ int git_repository_init_ext(
const char *wd;
bool is_valid;
git_oid_t oid_type = GIT_OID_DEFAULT;
git_refdb_t refdb_type = GIT_REFDB_FILES;
int error;
GIT_ASSERT_ARG(out);
@@ -2938,6 +2945,8 @@ int git_repository_init_ext(
if (opts->oid_type)
oid_type = opts->oid_type;
#endif
if (opts->refdb_type)
refdb_type = opts->refdb_type;
if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0)
goto out;
@@ -2957,13 +2966,15 @@ int git_repository_init_ext(
opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0)
if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode,
oid_type, refdb_type)) < 0)
goto out;
/* TODO: reinitialize the templates */
} else {
if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 ||
(error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0 ||
(error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode,
oid_type, refdb_type)) < 0 ||
(error = repo_init_head(repo_path.ptr, opts->initial_head)) < 0)
goto out;
}