refs: provide git_reference__is_per_worktree_ref()

Extract the function `is_per_worktree_ref()` from the "files" backend
and expose it via "refs.h". This function will be reused by the
"reftable" backend.
This commit is contained in:
Patrick Steinhardt
2026-04-02 08:29:33 +02:00
parent 641a43c90d
commit 61c7ff026b
3 changed files with 32 additions and 19 deletions

View File

@@ -487,21 +487,6 @@ static const char *loose_parse_symbolic(git_str *file_content)
return refname_start;
}
/*
* Returns whether a reference is stored per worktree or not.
* Per-worktree references are:
*
* - all pseudorefs, e.g. HEAD and MERGE_HEAD
* - all references stored inside of "refs/bisect/"
*/
static bool is_per_worktree_ref(const char *ref_name)
{
return git__prefixcmp(ref_name, "refs/") != 0 ||
git__prefixcmp(ref_name, "refs/bisect/") == 0 ||
git__prefixcmp(ref_name, "refs/worktree/") == 0 ||
git__prefixcmp(ref_name, "refs/rewritten/") == 0;
}
int git_reference__lookup_loose(
git_reference **out,
const char *ref_dir,
@@ -545,7 +530,7 @@ static int loose_lookup(
{
const char *ref_dir;
if (is_per_worktree_ref(ref_name))
if (git_reference__is_per_worktree_ref(ref_name))
ref_dir = backend->gitpath;
else
ref_dir = backend->commonpath;
@@ -989,11 +974,11 @@ static int iter_load_paths(
git_str_puts(&ctx->ref_name, entry->path);
if (worktree) {
if (!is_per_worktree_ref(ctx->ref_name.ptr))
if (!git_reference__is_per_worktree_ref(ctx->ref_name.ptr))
continue;
} else {
if (git_repository_is_worktree(ctx->backend->repo) &&
is_per_worktree_ref(ctx->ref_name.ptr))
git_reference__is_per_worktree_ref(ctx->ref_name.ptr))
continue;
}
@@ -1255,7 +1240,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
return GIT_EINVALIDSPEC;
}
if (is_per_worktree_ref(name))
if (git_reference__is_per_worktree_ref(name))
basedir = backend->gitpath;
else
basedir = backend->commonpath;

View File

@@ -1310,6 +1310,25 @@ int git_reference__is_pseudoref(const char *ref_name)
return 0;
}
int git_reference__is_per_worktree_ref(const char *ref_name)
{
const char * const worktree_refs[] = {
"refs/bisect/",
"refs/worktree/",
"refs/rewritten/",
};
size_t i;
if (git__prefixcmp(ref_name, "refs/") != 0)
return 1;
for (i = 0; i < ARRAY_SIZE(worktree_refs); i++)
if (git__prefixcmp(ref_name, worktree_refs[i]) == 0)
return 1;
return 0;
}
static int peel_error(int error, const git_reference *ref, const char *msg)
{
git_error_set(

View File

@@ -98,6 +98,15 @@ int git_reference__is_note(const char *ref_name);
int git_reference__is_pseudoref(const char *ref_name);
const char *git_reference__shorthand(const char *name);
/**
* Returns whether a reference is stored per worktree or not.
* Per-worktree references are:
*
* - all pseudorefs, e.g. HEAD and MERGE_HEAD
* - all references stored inside of "refs/bisect/"
*/
int git_reference__is_per_worktree_ref(const char *ref_name);
/*
* A `git_reference_cmp` wrapper suitable for passing to generic
* comparators, like `vector_cmp` / `tsort` / etc.