Commit 7edb9071da8e78e8cf9aff969f1b8137bca3c33d

Jeff King 2013-05-02T11:07:20

refdb_fs: do not require peeled packed refs to be tags Older versions of git would only write peeled entries for items under refs/tags/. Newer versions will write them for all refs, and we should be prepared to handle that.

diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 85444b6..9ee3568 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -132,10 +132,6 @@ static int packed_parse_peel(
 	if (tag_ref == NULL)
 		goto corrupt;
 
-	/* Ensure reference is a tag */
-	if (git__prefixcmp(tag_ref->name, GIT_REFS_TAGS_DIR) != 0)
-		goto corrupt;
-
 	if (buffer + GIT_OID_HEXSZ > buffer_end)
 		goto corrupt;
 
diff --git a/tests-clar/refs/peel.c b/tests-clar/refs/peel.c
index 34bd02c..f2fb6e2 100644
--- a/tests-clar/refs/peel.c
+++ b/tests-clar/refs/peel.c
@@ -1,19 +1,24 @@
 #include "clar_libgit2.h"
 
 static git_repository *g_repo;
+static git_repository *g_peel_repo;
 
 void test_refs_peel__initialize(void)
 {
 	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_open(&g_peel_repo, cl_fixture("peeled.git")));
 }
 
 void test_refs_peel__cleanup(void)
 {
 	git_repository_free(g_repo);
 	g_repo = NULL;
+	git_repository_free(g_peel_repo);
+	g_peel_repo = NULL;
 }
 
-static void assert_peel(
+static void assert_peel_generic(
+	git_repository *repo,
 	const char *ref_name,
 	git_otype requested_type,
 	const char* expected_sha,
@@ -23,7 +28,7 @@ static void assert_peel(
 	git_reference *ref;
 	git_object *peeled;
 
-	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_git_pass(git_reference_lookup(&ref, repo, ref_name));
 	
 	cl_git_pass(git_reference_peel(&peeled, ref, requested_type));
 
@@ -36,6 +41,16 @@ static void assert_peel(
 	git_reference_free(ref);
 }
 
+static void assert_peel(
+	const char *ref_name,
+	git_otype requested_type,
+	const char* expected_sha,
+	git_otype expected_type)
+{
+	assert_peel_generic(g_repo, ref_name, requested_type,
+			    expected_sha, expected_type);
+}
+
 static void assert_peel_error(int error, const char *ref_name, git_otype requested_type)
 {
 	git_reference *ref;
@@ -90,3 +105,15 @@ void test_refs_peel__can_peel_into_any_non_tag_object(void)
 	assert_peel("refs/tags/test", GIT_OBJ_ANY,
 		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
 }
+
+void test_refs_peel__can_peel_fully_peeled_packed_refs(void)
+{
+	assert_peel_generic(g_peel_repo,
+			    "refs/tags/tag-inside-tags", GIT_OBJ_ANY,
+			    "0df1a5865c8abfc09f1f2182e6a31be550e99f07",
+			    GIT_OBJ_COMMIT);
+	assert_peel_generic(g_peel_repo,
+			    "refs/foo/tag-outside-tags", GIT_OBJ_ANY,
+			    "0df1a5865c8abfc09f1f2182e6a31be550e99f07",
+			    GIT_OBJ_COMMIT);
+}
diff --git a/tests-clar/resources/peeled.git/HEAD b/tests-clar/resources/peeled.git/HEAD
new file mode 100644
index 0000000..cb089cd
--- /dev/null
+++ b/tests-clar/resources/peeled.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests-clar/resources/peeled.git/config b/tests-clar/resources/peeled.git/config
new file mode 100644
index 0000000..8830052
--- /dev/null
+++ b/tests-clar/resources/peeled.git/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+[remote "origin"]
+	url = /home/peff/compile/libgit2/tests-clar/resources/peeled
+	fetch = +refs/*:refs/*
+	mirror = true
diff --git a/tests-clar/resources/peeled.git/objects/info/packs b/tests-clar/resources/peeled.git/objects/info/packs
new file mode 100644
index 0000000..0d88b32
--- /dev/null
+++ b/tests-clar/resources/peeled.git/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack
+
diff --git a/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx b/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx
new file mode 100644
index 0000000..9b79e9b
Binary files /dev/null and b/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx differ
diff --git a/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack b/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack
new file mode 100644
index 0000000..2459ca2
Binary files /dev/null and b/tests-clar/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack differ
diff --git a/tests-clar/resources/peeled.git/packed-refs b/tests-clar/resources/peeled.git/packed-refs
new file mode 100644
index 0000000..ad053d5
--- /dev/null
+++ b/tests-clar/resources/peeled.git/packed-refs
@@ -0,0 +1,6 @@
+# pack-refs with: peeled fully-peeled 
+c2596aa0151888587ec5c0187f261e63412d9e11 refs/foo/tag-outside-tags
+^0df1a5865c8abfc09f1f2182e6a31be550e99f07
+0df1a5865c8abfc09f1f2182e6a31be550e99f07 refs/heads/master
+c2596aa0151888587ec5c0187f261e63412d9e11 refs/tags/tag-inside-tags
+^0df1a5865c8abfc09f1f2182e6a31be550e99f07
diff --git a/tests-clar/resources/peeled.git/refs/heads/master b/tests-clar/resources/peeled.git/refs/heads/master
new file mode 100644
index 0000000..76c15e2
--- /dev/null
+++ b/tests-clar/resources/peeled.git/refs/heads/master
@@ -0,0 +1 @@
+0df1a5865c8abfc09f1f2182e6a31be550e99f07