Skip to content

Commit 097f010

Browse files
committed
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.
1 parent 8f154be commit 097f010

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/refdb_fs.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
738738
{
739739
int error;
740740
git_buf ref_path = GIT_BUF_INIT;
741+
const char *basedir;
741742

742743
assert(file && backend && name);
743744

@@ -746,13 +747,18 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
746747
return GIT_EINVALIDSPEC;
747748
}
748749

750+
if (is_per_worktree_ref(name))
751+
basedir = backend->gitpath;
752+
else
753+
basedir = backend->commonpath;
754+
749755
/* Remove a possibly existing empty directory hierarchy
750756
* which name would collide with the reference name
751757
*/
752-
if ((error = git_futils_rmdir_r(name, backend->gitpath, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
758+
if ((error = git_futils_rmdir_r(name, basedir, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
753759
return error;
754760

755-
if (git_buf_joinpath(&ref_path, backend->gitpath, name) < 0)
761+
if (git_buf_joinpath(&ref_path, basedir, name) < 0)
756762
return -1;
757763

758764
error = git_filebuf_open(file, ref_path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE);

tests/worktree/refs.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "clar_libgit2.h"
2+
#include "path.h"
3+
#include "refs.h"
24
#include "worktree.h"
35
#include "worktree_helpers.h"
46

@@ -128,3 +130,27 @@ void test_worktree_refs__delete_succeeds_after_pruning_worktree(void)
128130
cl_git_pass(git_branch_delete(branch));
129131
git_reference_free(branch);
130132
}
133+
134+
void test_worktree_refs__creating_refs_uses_commondir(void)
135+
{
136+
git_reference *head, *branch, *lookup;
137+
git_commit *commit;
138+
git_buf refpath = GIT_BUF_INIT;
139+
140+
cl_git_pass(git_buf_joinpath(&refpath,
141+
git_repository_commondir(fixture.worktree), "refs/heads/testbranch"));
142+
cl_assert(!git_path_exists(refpath.ptr));
143+
144+
cl_git_pass(git_repository_head(&head, fixture.worktree));
145+
cl_git_pass(git_commit_lookup(&commit, fixture.worktree, git_reference_target(head)));
146+
cl_git_pass(git_branch_create(&branch, fixture.worktree, "testbranch", commit, 0));
147+
cl_git_pass(git_branch_lookup(&lookup, fixture.worktree, "testbranch", GIT_BRANCH_LOCAL));
148+
cl_assert(git_reference_cmp(branch, lookup) == 0);
149+
cl_assert(git_path_exists(refpath.ptr));
150+
151+
git_reference_free(lookup);
152+
git_reference_free(branch);
153+
git_reference_free(head);
154+
git_commit_free(commit);
155+
git_buf_free(&refpath);
156+
}

0 commit comments

Comments
 (0)