refdb_fs: expose function to read a loose ref

Expose a function to read a loose reference. This function will be used
in a subsequent commit to read pseudo-refs on the generic refdb layer.
This commit is contained in:
Patrick Steinhardt
2025-07-14 12:40:01 +02:00
parent 93d77d1cb5
commit 7f35dc5817
2 changed files with 33 additions and 16 deletions

View File

@@ -502,46 +502,57 @@ static bool is_per_worktree_ref(const char *ref_name)
git__prefixcmp(ref_name, "refs/rewritten/") == 0; git__prefixcmp(ref_name, "refs/rewritten/") == 0;
} }
static int loose_lookup( int git_reference__lookup_loose(
git_reference **out, git_reference **out,
refdb_fs_backend *backend, const char *ref_dir,
const char *ref_name) const char *ref_name,
git_oid_t oid_type)
{ {
git_str ref_file = GIT_STR_INIT; git_str buf = GIT_STR_INIT;
int error = 0; int error = 0;
const char *ref_dir;
if (out) if (out)
*out = NULL; *out = NULL;
if (is_per_worktree_ref(ref_name)) if ((error = git_str_joinpath(&buf, ref_dir, ref_name)) < 0 ||
ref_dir = backend->gitpath; (error = git_futils_readbuffer(&buf, buf.ptr)) < 0)
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_str_cstr(&ref_file), GIT_SYMREF) == 0) { else if (git__prefixcmp(git_str_cstr(&buf), GIT_SYMREF) == 0) {
const char *target; const char *target;
git_str_rtrim(&ref_file); git_str_rtrim(&buf);
if (!(target = loose_parse_symbolic(&ref_file))) if (!(target = loose_parse_symbolic(&buf)))
error = -1; error = -1;
else if (out != NULL) else if (out != NULL)
*out = git_reference__alloc_symbolic(ref_name, target); *out = git_reference__alloc_symbolic(ref_name, target);
} else { } else {
git_oid oid; git_oid oid;
if (!(error = loose_parse_oid(&oid, ref_name, &ref_file, backend->oid_type)) && if (!(error = loose_parse_oid(&oid, ref_name, &buf, oid_type)) &&
out != NULL) out != NULL)
*out = git_reference__alloc(ref_name, &oid, NULL); *out = git_reference__alloc(ref_name, &oid, NULL);
} }
git_str_dispose(&ref_file); git_str_dispose(&buf);
return error; return error;
} }
static int loose_lookup(
git_reference **out,
refdb_fs_backend *backend,
const char *ref_name)
{
const char *ref_dir;
if (is_per_worktree_ref(ref_name))
ref_dir = backend->gitpath;
else
ref_dir = backend->commonpath;
return git_reference__lookup_loose(out, ref_dir, ref_name, backend->oid_type);
}
static int ref_error_notfound(const char *name) static int ref_error_notfound(const char *name)
{ {
git_error_set(GIT_ERROR_REFERENCE, "reference '%s' not found", name); git_error_set(GIT_ERROR_REFERENCE, "reference '%s' not found", name);

View File

@@ -128,6 +128,12 @@ int git_reference_lookup_resolved(
int git_reference__log_signature(git_signature **out, git_repository *repo); int git_reference__log_signature(git_signature **out, git_repository *repo);
int git_reference__lookup_loose(
git_reference **out,
const char *ref_dir,
const char *ref_name,
git_oid_t oid_type);
/** Update a reference after a commit. */ /** Update a reference after a commit. */
int git_reference__update_for_commit( int git_reference__update_for_commit(
git_repository *repo, git_repository *repo,