diff --git a/src/refs.c b/src/refs.c index 9661988cc..00b9ff6b2 100644 --- a/src/refs.c +++ b/src/refs.c @@ -746,7 +746,7 @@ static int packed_write_ref(reference_oid *ref, git_filebuf *file) */ static int packed_find_peel(reference_oid *ref) { - git_tag *tag; + git_object *object; int error; if (ref->ref.type & GIT_REF_HAS_PEEL) @@ -760,25 +760,32 @@ static int packed_find_peel(reference_oid *ref) return GIT_SUCCESS; /* - * Find the tag in the repository. The tag must exist, - * otherwise this reference is broken and we shouldn't - * pack it. + * Find the tagged object in the repository */ - error = git_tag_lookup(&tag, ref->ref.owner, &ref->oid); + error = git_object_lookup(&object, ref->ref.owner, &ref->oid, GIT_OBJ_ANY); if (error < GIT_SUCCESS) return GIT_EOBJCORRUPTED; /* - * Find the object pointed at by this tag + * If the tagged object is a Tag object, we need to resolve it; + * if the ref is actually a 'weak' ref, we don't need to resolve + * anything. */ - git_oid_cpy(&ref->peel_target, git_tag_target_oid(tag)); - ref->ref.type |= GIT_REF_HAS_PEEL; + if (git_object_type(object) == GIT_OBJ_TAG) { + git_tag *tag = (git_tag *)object; - /* - * The reference has now cached the resolved OID, and is - * marked at such. When written to the packfile, it'll be - * accompanied by this resolved oid - */ + /* + * Find the object pointed at by this tag + */ + git_oid_cpy(&ref->peel_target, git_tag_target_oid(tag)); + ref->ref.type |= GIT_REF_HAS_PEEL; + + /* + * The reference has now cached the resolved OID, and is + * marked at such. When written to the packfile, it'll be + * accompanied by this resolved oid + */ + } return GIT_SUCCESS; } @@ -1419,6 +1426,10 @@ int git_reference_delete(git_reference *ref) assert(ref); if (ref->type & GIT_REF_PACKED) { + /* load the existing packfile */ + if ((error = packed_load(ref->owner)) < GIT_SUCCESS) + return error; + git_hashtable_remove(ref->owner->references.packfile, ref->name); error = packed_write(ref->owner); } else { diff --git a/tests/resources/testrepo.git/refs/tags/point_to_blob b/tests/resources/testrepo.git/refs/tags/point_to_blob new file mode 100644 index 000000000..f874a3ffc Binary files /dev/null and b/tests/resources/testrepo.git/refs/tags/point_to_blob differ diff --git a/tests/t10-refs.c b/tests/t10-refs.c index 2797cd8ac..a6a560193 100644 --- a/tests/t10-refs.c +++ b/tests/t10-refs.c @@ -456,6 +456,11 @@ BEGIN_TEST(pack1, "create a packfile from all the loose rn a repo") must_be_true((reference->type & GIT_REF_PACKED) == 0); must_be_true(strcmp(reference->name, loose_tag_ref_name) == 0); + /* + * We are now trying to pack also a loose reference + * called `points_to_blob`, to make sure we can properly + * pack weak tags + */ must_pass(git_reference_packall(repo)); /* Ensure the packed-refs file exists */ @@ -877,10 +882,10 @@ BEGIN_TEST(list0, "try to list all the references in our test repo") printf("# %s\n", ref_list.strings[i]); }*/ - /* We have exactly 7 refs in total if we include the packed ones: + /* We have exactly 8 refs in total if we include the packed ones: * there is a reference that exists both in the packfile and as * loose, but we only list it once */ - must_be_true(ref_list.count == 7); + must_be_true(ref_list.count == 8); git_strarray_free(&ref_list); git_repository_free(repo);