mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-16 22:30:31 +00:00
refdb: introduce commondir awareness
The refdb_fs_backend is not aware of the git commondir, which stores common objects like the o bject database and packed/loose refereensces when worktrees are used. Make refdb_fs_backend aware of the common directory by introducing a new commonpath variable that points to the actual common path of the database and using it instead of the gitdir for the mentioned objects.
This commit is contained in:
parent
71dd086195
commit
e0a6c28eb3
@ -57,6 +57,8 @@ typedef struct refdb_fs_backend {
|
|||||||
git_repository *repo;
|
git_repository *repo;
|
||||||
/* path to git directory */
|
/* path to git directory */
|
||||||
char *gitpath;
|
char *gitpath;
|
||||||
|
/* path to common objects' directory */
|
||||||
|
char *commonpath;
|
||||||
|
|
||||||
git_sortedcache *refcache;
|
git_sortedcache *refcache;
|
||||||
int peeling_mode;
|
int peeling_mode;
|
||||||
@ -363,6 +365,14 @@ static const char *loose_parse_symbolic(git_buf *file_content)
|
|||||||
return refname_start;
|
return refname_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_per_worktree_ref(const char *ref_name)
|
||||||
|
{
|
||||||
|
return strcmp("HEAD", ref_name) == 0 ||
|
||||||
|
strcmp("FETCH_HEAD", ref_name) == 0 ||
|
||||||
|
strcmp("MERGE_HEAD", ref_name) == 0 ||
|
||||||
|
strcmp("ORIG_HEAD", ref_name) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int loose_lookup(
|
static int loose_lookup(
|
||||||
git_reference **out,
|
git_reference **out,
|
||||||
refdb_fs_backend *backend,
|
refdb_fs_backend *backend,
|
||||||
@ -370,11 +380,17 @@ static int loose_lookup(
|
|||||||
{
|
{
|
||||||
git_buf ref_file = GIT_BUF_INIT;
|
git_buf ref_file = GIT_BUF_INIT;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
const char *ref_dir;
|
||||||
|
|
||||||
if (out)
|
if (out)
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
|
|
||||||
if ((error = loose_readbuffer(&ref_file, backend->gitpath, ref_name)) < 0)
|
if (is_per_worktree_ref(ref_name))
|
||||||
|
ref_dir = backend->gitpath;
|
||||||
|
else
|
||||||
|
ref_dir = backend->commonpath;
|
||||||
|
|
||||||
|
if ((error = loose_readbuffer(&ref_file, ref_dir, ref_name)) < 0)
|
||||||
/* cannot read loose ref file - gah */;
|
/* cannot read loose ref file - gah */;
|
||||||
else if (git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF) == 0) {
|
else if (git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF) == 0) {
|
||||||
const char *target;
|
const char *target;
|
||||||
@ -485,12 +501,12 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
|
|||||||
git_iterator_options fsit_opts = GIT_ITERATOR_OPTIONS_INIT;
|
git_iterator_options fsit_opts = GIT_ITERATOR_OPTIONS_INIT;
|
||||||
const git_index_entry *entry = NULL;
|
const git_index_entry *entry = NULL;
|
||||||
|
|
||||||
if (!backend->gitpath) /* do nothing if no gitpath for loose refs */
|
if (!backend->commonpath) /* do nothing if no commonpath for loose refs */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fsit_opts.flags = backend->iterator_flags;
|
fsit_opts.flags = backend->iterator_flags;
|
||||||
|
|
||||||
if ((error = git_buf_printf(&path, "%s/refs", backend->gitpath)) < 0 ||
|
if ((error = git_buf_printf(&path, "%s/refs", backend->commonpath)) < 0 ||
|
||||||
(error = git_iterator_for_filesystem(&fsit, path.ptr, &fsit_opts)) < 0) {
|
(error = git_iterator_for_filesystem(&fsit, path.ptr, &fsit_opts)) < 0) {
|
||||||
git_buf_free(&path);
|
git_buf_free(&path);
|
||||||
return error;
|
return error;
|
||||||
@ -1410,6 +1426,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
|
|||||||
|
|
||||||
git_sortedcache_free(backend->refcache);
|
git_sortedcache_free(backend->refcache);
|
||||||
git__free(backend->gitpath);
|
git__free(backend->gitpath);
|
||||||
|
git__free(backend->commonpath);
|
||||||
git__free(backend);
|
git__free(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,6 +1437,8 @@ static int setup_namespace(git_buf *gitpath, git_repository *repo)
|
|||||||
/* Not all repositories have a gitpath */
|
/* Not all repositories have a gitpath */
|
||||||
if (repo->path_repository == NULL)
|
if (repo->path_repository == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (repo->commondir == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Load the path to the repo first */
|
/* Load the path to the repo first */
|
||||||
git_buf_puts(gitpath, repo->path_repository);
|
git_buf_puts(gitpath, repo->path_repository);
|
||||||
@ -1446,7 +1465,7 @@ static int setup_namespace(git_buf *gitpath, git_repository *repo)
|
|||||||
git__free(parts);
|
git__free(parts);
|
||||||
|
|
||||||
/* Make sure that the folder with the namespace exists */
|
/* Make sure that the folder with the namespace exists */
|
||||||
if (git_futils_mkdir_relative(git_buf_cstr(gitpath), repo->path_repository,
|
if (git_futils_mkdir_relative(git_buf_cstr(gitpath), repo->commondir,
|
||||||
0777, GIT_MKDIR_PATH, NULL) < 0)
|
0777, GIT_MKDIR_PATH, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1960,9 +1979,11 @@ int git_refdb_backend_fs(
|
|||||||
if (setup_namespace(&gitpath, repository) < 0)
|
if (setup_namespace(&gitpath, repository) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
backend->gitpath = git_buf_detach(&gitpath);
|
backend->gitpath = backend->commonpath = git_buf_detach(&gitpath);
|
||||||
|
if (repository->commondir)
|
||||||
|
backend->commonpath = git__strdup(repository->commondir);
|
||||||
|
|
||||||
if (git_buf_joinpath(&gitpath, backend->gitpath, GIT_PACKEDREFS_FILE) < 0 ||
|
if (git_buf_joinpath(&gitpath, backend->commonpath, GIT_PACKEDREFS_FILE) < 0 ||
|
||||||
git_sortedcache_new(
|
git_sortedcache_new(
|
||||||
&backend->refcache, offsetof(struct packref, name),
|
&backend->refcache, offsetof(struct packref, name),
|
||||||
NULL, NULL, packref_cmp, git_buf_cstr(&gitpath)) < 0)
|
NULL, NULL, packref_cmp, git_buf_cstr(&gitpath)) < 0)
|
||||||
@ -2002,6 +2023,7 @@ int git_refdb_backend_fs(
|
|||||||
fail:
|
fail:
|
||||||
git_buf_free(&gitpath);
|
git_buf_free(&gitpath);
|
||||||
git__free(backend->gitpath);
|
git__free(backend->gitpath);
|
||||||
|
git__free(backend->commonpath);
|
||||||
git__free(backend);
|
git__free(backend);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
68
tests/worktree/refs.c
Normal file
68
tests/worktree/refs.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "clar_libgit2.h"
|
||||||
|
#include "worktree_helpers.h"
|
||||||
|
|
||||||
|
#define COMMON_REPO "testrepo"
|
||||||
|
#define WORKTREE_REPO "testrepo-worktree"
|
||||||
|
|
||||||
|
static worktree_fixture fixture =
|
||||||
|
WORKTREE_FIXTURE_INIT(COMMON_REPO, WORKTREE_REPO);
|
||||||
|
|
||||||
|
void test_worktree_refs__initialize(void)
|
||||||
|
{
|
||||||
|
setup_fixture_worktree(&fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_refs__cleanup(void)
|
||||||
|
{
|
||||||
|
cleanup_fixture_worktree(&fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_refs__list(void)
|
||||||
|
{
|
||||||
|
git_strarray refs, wtrefs;
|
||||||
|
unsigned i, j;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
cl_git_pass(git_reference_list(&refs, fixture.repo));
|
||||||
|
cl_git_pass(git_reference_list(&wtrefs, fixture.worktree));
|
||||||
|
|
||||||
|
if (refs.count != wtrefs.count)
|
||||||
|
{
|
||||||
|
error = GIT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < refs.count; i++)
|
||||||
|
{
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < wtrefs.count; j++)
|
||||||
|
{
|
||||||
|
if (!strcmp(refs.strings[i], wtrefs.strings[j]))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
error = GIT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
git_strarray_free(&refs);
|
||||||
|
git_strarray_free(&wtrefs);
|
||||||
|
cl_git_pass(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_refs__read_head(void)
|
||||||
|
{
|
||||||
|
git_reference *head;
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_head(&head, fixture.worktree));
|
||||||
|
|
||||||
|
git_reference_free(head);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user