Skip to content

Commit b112b1e

Browse files
committed
refs: do not use peeled OID if peeling to a tag
If a reference stored in a packed-refs file does not directly point to a commit, tree or blob, the packed-refs file will also will include a fully-peeled OID pointing to the first underlying object of that type. If we try to peel a reference to an object, we will use that peeled OID to speed up resolving the object. As a reference for an annotated tag does not directly point to a commit, tree or blob but instead to the tag object, the packed-refs file will have an accomodating fully-peeled OID pointing to the object referenced by that tag. When we use the fully-peeled OID pointing to the referenced object when peeling, we obviously cannot peel that to the tag anymore. Fix this issue by not using the fully-peeled OID whenever we want to peel to a tag. Note that this does not include the case where we want to resolve to _any_ object type. Existing code may make use from the fact that we resolve those to commit objects instead of tag objects, even though that behaviour is inconsistent between packed and loose references. Furthermore, some tests of ours make the assumption that we in fact resolve those references to a commit.
1 parent c7c5f2c commit b112b1e

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

src/refs.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1360,7 +1360,13 @@ int git_reference_peel(
13601360
return peel_error(error, ref, "Cannot resolve reference");
13611361
}
13621362

1363-
if (!git_oid_iszero(&resolved->peel)) {
1363+
/*
1364+
* If we try to peel an object to a tag, we cannot use
1365+
* the fully peeled object, as that will always resolve
1366+
* to a commit. So we only want to use the peeled value
1367+
* if it is not zero and the target is not a tag.
1368+
*/
1369+
if (target_type != GIT_OBJ_TAG && !git_oid_iszero(&resolved->peel)) {
13641370
error = git_object_lookup(&target,
13651371
git_reference_owner(ref), &resolved->peel, GIT_OBJ_ANY);
13661372
} else {

tests/refs/peel.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,15 @@ void test_refs_peel__can_peel_fully_peeled_packed_refs(void)
117117
"0df1a5865c8abfc09f1f2182e6a31be550e99f07",
118118
GIT_OBJ_COMMIT);
119119
}
120+
121+
void test_refs_peel__can_peel_fully_peeled_tag_to_tag(void)
122+
{
123+
assert_peel_generic(g_peel_repo,
124+
"refs/tags/tag-inside-tags", GIT_OBJ_TAG,
125+
"c2596aa0151888587ec5c0187f261e63412d9e11",
126+
GIT_OBJ_TAG);
127+
assert_peel_generic(g_peel_repo,
128+
"refs/foo/tag-outside-tags", GIT_OBJ_TAG,
129+
"c2596aa0151888587ec5c0187f261e63412d9e11",
130+
GIT_OBJ_TAG);
131+
}

0 commit comments

Comments
 (0)