Commit 097f0105 by Patrick Steinhardt

refdb: create references in commondir

References for a repository are usually created inside of its gitdir.
When using worktrees, though, these references are not to be created
inside the worktree gitdir, but instead inside the gitdir of its parent
repository, which is the commondir. Like this, branches will still be
available after the worktree itself has been deleted.

The filesystem refdb currently still creates new references inside of
the gitdir. Fix this and have it create references in commondir.
parent 8f154be3
......@@ -738,6 +738,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
{
int error;
git_buf ref_path = GIT_BUF_INIT;
const char *basedir;
assert(file && backend && name);
......@@ -746,13 +747,18 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
return GIT_EINVALIDSPEC;
}
if (is_per_worktree_ref(name))
basedir = backend->gitpath;
else
basedir = backend->commonpath;
/* Remove a possibly existing empty directory hierarchy
* which name would collide with the reference name
*/
if ((error = git_futils_rmdir_r(name, backend->gitpath, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
if ((error = git_futils_rmdir_r(name, basedir, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
return error;
if (git_buf_joinpath(&ref_path, backend->gitpath, name) < 0)
if (git_buf_joinpath(&ref_path, basedir, name) < 0)
return -1;
error = git_filebuf_open(file, ref_path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE);
......
#include "clar_libgit2.h"
#include "path.h"
#include "refs.h"
#include "worktree.h"
#include "worktree_helpers.h"
......@@ -128,3 +130,27 @@ void test_worktree_refs__delete_succeeds_after_pruning_worktree(void)
cl_git_pass(git_branch_delete(branch));
git_reference_free(branch);
}
void test_worktree_refs__creating_refs_uses_commondir(void)
{
git_reference *head, *branch, *lookup;
git_commit *commit;
git_buf refpath = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&refpath,
git_repository_commondir(fixture.worktree), "refs/heads/testbranch"));
cl_assert(!git_path_exists(refpath.ptr));
cl_git_pass(git_repository_head(&head, fixture.worktree));
cl_git_pass(git_commit_lookup(&commit, fixture.worktree, git_reference_target(head)));
cl_git_pass(git_branch_create(&branch, fixture.worktree, "testbranch", commit, 0));
cl_git_pass(git_branch_lookup(&lookup, fixture.worktree, "testbranch", GIT_BRANCH_LOCAL));
cl_assert(git_reference_cmp(branch, lookup) == 0);
cl_assert(git_path_exists(refpath.ptr));
git_reference_free(lookup);
git_reference_free(branch);
git_reference_free(head);
git_commit_free(commit);
git_buf_free(&refpath);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment