From 7f35dc5817d07bdfb831bcd50fb5bfeedafb6ea0 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 14 Jul 2025 12:40:01 +0200 Subject: [PATCH] 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. --- src/libgit2/refdb_fs.c | 43 ++++++++++++++++++++++++++---------------- src/libgit2/refs.h | 6 ++++++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/libgit2/refdb_fs.c b/src/libgit2/refdb_fs.c index 515b9c484..66478abb6 100644 --- a/src/libgit2/refdb_fs.c +++ b/src/libgit2/refdb_fs.c @@ -502,46 +502,57 @@ static bool is_per_worktree_ref(const char *ref_name) git__prefixcmp(ref_name, "refs/rewritten/") == 0; } -static int loose_lookup( +int git_reference__lookup_loose( git_reference **out, - refdb_fs_backend *backend, - const char *ref_name) + const char *ref_dir, + 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; - const char *ref_dir; if (out) *out = NULL; - 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) + if ((error = git_str_joinpath(&buf, ref_dir, ref_name)) < 0 || + (error = git_futils_readbuffer(&buf, buf.ptr)) < 0) /* 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; - git_str_rtrim(&ref_file); + git_str_rtrim(&buf); - if (!(target = loose_parse_symbolic(&ref_file))) + if (!(target = loose_parse_symbolic(&buf))) error = -1; else if (out != NULL) *out = git_reference__alloc_symbolic(ref_name, target); } else { 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 = git_reference__alloc(ref_name, &oid, NULL); } - git_str_dispose(&ref_file); + git_str_dispose(&buf); 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) { git_error_set(GIT_ERROR_REFERENCE, "reference '%s' not found", name); diff --git a/src/libgit2/refs.h b/src/libgit2/refs.h index 5b89a666b..0e31d9122 100644 --- a/src/libgit2/refs.h +++ b/src/libgit2/refs.h @@ -128,6 +128,12 @@ int git_reference_lookup_resolved( 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. */ int git_reference__update_for_commit( git_repository *repo,