shithub: furgit

Download patch

ref: 3a4b0c924197ba6d9570c8ac338c32b8093398da
parent: 65600ea051adc75d09e9763fb6e11e79602f76b6
author: Runxi Yu <me@runxiyu.org>
date: Sat Nov 22 03:00:00 EST 2025

obj: Add ReadObjectTypeRaw

--- a/obj.go
+++ b/obj.go
@@ -116,6 +116,32 @@
 	return obj, parseErr
 }
 
+// ReadObjectTypeRaw reads the object type and raw body.
+func (repo *Repository) ReadObjectTypeRaw(id Hash) (ObjectType, []byte, error) {
+	ty, body, err := repo.looseRead(id)
+	if err == nil {
+		return ty, body.Bytes(), nil
+	}
+	if !errors.Is(err, ErrNotFound) {
+		return ObjectTypeInvalid, nil, err
+	}
+	ty, body, err = repo.packRead(id)
+	if errors.Is(err, ErrNotFound) {
+		return ObjectTypeInvalid, nil, ErrNotFound
+	}
+	if err != nil {
+		return ObjectTypeInvalid, nil, err
+	}
+	return ty, body.Bytes(), nil
+	// note to self: It always feels wrong to not call .Release in places like
+	// this but this is actually correct; we're returning the underlying buffer
+	// to the user who should not be aware of our internal buffer pooling.
+	// Releasing this buffer back to the pool would lead to a use-after-free;
+	// not releasing it as we do here, means it gets GC'ed.
+	// Copying into a newly allocated buffer is even worse as it incurs
+	// unnecessary copy overhead.
+}
+
 // ReadObjectTypeSize reports the object type and size.
 //
 // Typicall, this is more efficient than reading the full object,
--