Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e5a7210

Browse files
committed
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.
1 parent a4a0d87 commit e5a7210

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/libgit2/refs.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ int git_reference_lookup_resolved(
231231
GIT_ASSERT_ARG(repo);
232232
GIT_ASSERT_ARG(name);
233233

234+
/*
235+
* Pseudorefs are not stored in the reference backend, as they may
236+
* contain additional data that doesn't even follow the normal ref
237+
* format. So we look these up as "loose" refs directly.
238+
*/
239+
if (git_reference__is_pseudoref(name))
240+
return git_reference__lookup_loose(ref_out, repo->gitdir, name, repo->oid_type);
241+
234242
if ((error = reference_normalize_for_repo(normalized, repo, name, true)) < 0 ||
235243
(error = git_repository_refdb__weakptr(&refdb, repo)) < 0 ||
236244
(error = git_refdb_resolve(ref_out, refdb, normalized, max_nesting)) < 0)
@@ -1278,6 +1286,21 @@ int git_reference_is_note(const git_reference *ref)
12781286
return git_reference__is_note(ref->name);
12791287
}
12801288

1289+
int git_reference__is_pseudoref(const char *ref_name)
1290+
{
1291+
const char * const pseudorefs[] = {
1292+
"MERGE_HEAD",
1293+
"FETCH_HEAD",
1294+
};
1295+
size_t i;
1296+
1297+
for (i = 0; i < ARRAY_SIZE(pseudorefs); i++)
1298+
if (git__strcmp(ref_name, pseudorefs[i]) == 0)
1299+
return 1;
1300+
1301+
return 0;
1302+
}
1303+
12811304
static int peel_error(int error, const git_reference *ref, const char *msg)
12821305
{
12831306
git_error_set(

src/libgit2/refs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ int git_reference__is_branch(const char *ref_name);
9595
int git_reference__is_remote(const char *ref_name);
9696
int git_reference__is_tag(const char *ref_name);
9797
int git_reference__is_note(const char *ref_name);
98+
int git_reference__is_pseudoref(const char *ref_name);
9899
const char *git_reference__shorthand(const char *name);
99100

100101
/*

0 commit comments

Comments
 (0)