repository: wire up refStorage extension

To support multiple different reference backend implementations,
Git introduced a "refStorage" extension that stores the reference
storage format a Git client should try to use.

Wire up the logic to read this new extension when we open a repository
from disk. For now, only the "files" backend is supported by us. When
trying to open a repository that has a refstorage format that we don't
understand we now error out.

There are two functions that create a new repository that doesn't really
have references. While those are mostly non-functional when it comes to
references, we do expect that you can access the refdb, even if it's not
yielding any refs. For now we mark those to use the "files" backend, so
that the status quo is retained. Eventually though it might not be the
worst idea to introduce an explicit "in-memory" reference database. But
that is outside the scope of this patch series.
This commit is contained in:
Patrick Steinhardt
2025-02-06 12:25:07 +01:00
parent 38382ce3bc
commit 806a0062fd
7 changed files with 120 additions and 20 deletions

View File

@@ -34,11 +34,12 @@ void test_core_opts__extensions_query(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 4);
cl_assert_equal_sz(out.count, 5);
cl_assert_equal_s("noop", out.strings[0]);
cl_assert_equal_s("objectformat", out.strings[1]);
cl_assert_equal_s("preciousobjects", out.strings[2]);
cl_assert_equal_s("worktreeconfig", out.strings[3]);
cl_assert_equal_s("refstorage", out.strings[3]);
cl_assert_equal_s("worktreeconfig", out.strings[4]);
git_strarray_dispose(&out);
}
@@ -51,12 +52,13 @@ void test_core_opts__extensions_add(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 5);
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_s("foo", out.strings[0]);
cl_assert_equal_s("noop", out.strings[1]);
cl_assert_equal_s("objectformat", out.strings[2]);
cl_assert_equal_s("preciousobjects", out.strings[3]);
cl_assert_equal_s("worktreeconfig", out.strings[4]);
cl_assert_equal_s("refstorage", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
git_strarray_dispose(&out);
}
@@ -69,12 +71,13 @@ void test_core_opts__extensions_remove(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 5);
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_s("bar", out.strings[0]);
cl_assert_equal_s("baz", out.strings[1]);
cl_assert_equal_s("objectformat", out.strings[2]);
cl_assert_equal_s("preciousobjects", out.strings[3]);
cl_assert_equal_s("worktreeconfig", out.strings[4]);
cl_assert_equal_s("refstorage", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
git_strarray_dispose(&out);
}
@@ -87,13 +90,14 @@ void test_core_opts__extensions_uniq(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_sz(out.count, 7);
cl_assert_equal_s("bar", out.strings[0]);
cl_assert_equal_s("foo", out.strings[1]);
cl_assert_equal_s("noop", out.strings[2]);
cl_assert_equal_s("objectformat", out.strings[3]);
cl_assert_equal_s("preciousobjects", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
cl_assert_equal_s("refstorage", out.strings[5]);
cl_assert_equal_s("worktreeconfig", out.strings[6]);
git_strarray_dispose(&out);
}

View File

@@ -874,3 +874,26 @@ void test_repo_open__can_reset_safe_directory_list(void)
git_str_dispose(&config_filename);
git_str_dispose(&config_data);
}
void test_repo_open__refstorage_extension(void)
{
git_repository *repo, *tmp;
git_config *config;
repo = cl_git_sandbox_init("empty_bare.git");
cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
cl_git_pass(git_config_set_string(config, "extensions.refStorage", "files"));
cl_git_pass(git_repository_open(&tmp, "empty_bare.git"));
git_repository_free(tmp);
cl_git_pass(git_config_set_string(config, "extensions.refStorage", "garbage"));
cl_git_fail_with(GIT_EINVALID, git_repository_open(&tmp, "empty_bare.git"));
git_repository_free(tmp);
git_config_free(config);
git_repository_free(repo);
}