mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
refs: always read pseudorefs as loose refs
Regardless of which reference storage format is used, pseudorefs will always be looked up via the filesystem as loose refs. This is because pseudorefs do not strictly follow the reference format and may contain additional metadata that is not present in a normal reference. We don't honor this in `git_reference_lookup()` though but instead defer to the refdb to read such references. This obviously works just fine with the "files" backend, but any other backend would have to grow custom logic to handle reading pseudorefs. Refactor `git_reference_lookup_resolved()` so that it knows to always read pseudorefs as loose references. This allows refdb implementations to not care about pseudoref handling at all.
This commit is contained in:
@@ -231,6 +231,14 @@ int git_reference_lookup_resolved(
|
||||
GIT_ASSERT_ARG(repo);
|
||||
GIT_ASSERT_ARG(name);
|
||||
|
||||
/*
|
||||
* Pseudorefs are not stored in the reference backend, as they may
|
||||
* contain additional data that doesn't even follow the normal ref
|
||||
* format. So we look these up as "loose" refs directly.
|
||||
*/
|
||||
if (git_reference__is_pseudoref(name))
|
||||
return git_reference__lookup_loose(ref_out, repo->gitdir, name, repo->oid_type);
|
||||
|
||||
if ((error = reference_normalize_for_repo(normalized, repo, name, true)) < 0 ||
|
||||
(error = git_repository_refdb__weakptr(&refdb, repo)) < 0 ||
|
||||
(error = git_refdb_resolve(ref_out, refdb, normalized, max_nesting)) < 0)
|
||||
@@ -1278,6 +1286,21 @@ int git_reference_is_note(const git_reference *ref)
|
||||
return git_reference__is_note(ref->name);
|
||||
}
|
||||
|
||||
int git_reference__is_pseudoref(const char *ref_name)
|
||||
{
|
||||
const char * const pseudorefs[] = {
|
||||
"MERGE_HEAD",
|
||||
"FETCH_HEAD",
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pseudorefs); i++)
|
||||
if (git__strcmp(ref_name, pseudorefs[i]) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int peel_error(int error, const git_reference *ref, const char *msg)
|
||||
{
|
||||
git_error_set(
|
||||
|
||||
@@ -95,6 +95,7 @@ int git_reference__is_branch(const char *ref_name);
|
||||
int git_reference__is_remote(const char *ref_name);
|
||||
int git_reference__is_tag(const char *ref_name);
|
||||
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);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user