Commit e2e3943db59e034cfbe082b321fe6205576ce348

Edward Thomson 2017-10-07T00:22:22

Merge pull request #4367 from pks-t/pks/peel-peeled-to-tag refs: do not use peeled OID if peeling to a tag

diff --git a/src/refs.c b/src/refs.c
index 9420540..550963e 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -1360,7 +1360,13 @@ int git_reference_peel(
 			return peel_error(error, ref, "Cannot resolve reference");
 	}
 
-	if (!git_oid_iszero(&resolved->peel)) {
+	/*
+	 * If we try to peel an object to a tag, we cannot use
+	 * the fully peeled object, as that will always resolve
+	 * to a commit. So we only want to use the peeled value
+	 * if it is not zero and the target is not a tag.
+	 */
+	if (target_type != GIT_OBJ_TAG && !git_oid_iszero(&resolved->peel)) {
 		error = git_object_lookup(&target,
 			git_reference_owner(ref), &resolved->peel, GIT_OBJ_ANY);
 	} else {
diff --git a/tests/refs/peel.c b/tests/refs/peel.c
index 83f6109..09809e1 100644
--- a/tests/refs/peel.c
+++ b/tests/refs/peel.c
@@ -117,3 +117,15 @@ void test_refs_peel__can_peel_fully_peeled_packed_refs(void)
 			    "0df1a5865c8abfc09f1f2182e6a31be550e99f07",
 			    GIT_OBJ_COMMIT);
 }
+
+void test_refs_peel__can_peel_fully_peeled_tag_to_tag(void)
+{
+	assert_peel_generic(g_peel_repo,
+			    "refs/tags/tag-inside-tags", GIT_OBJ_TAG,
+			    "c2596aa0151888587ec5c0187f261e63412d9e11",
+			    GIT_OBJ_TAG);
+	assert_peel_generic(g_peel_repo,
+			    "refs/foo/tag-outside-tags", GIT_OBJ_TAG,
+			    "c2596aa0151888587ec5c0187f261e63412d9e11",
+			    GIT_OBJ_TAG);
+}