+void *read_object_with_reference(const unsigned char *sha1,
+ const unsigned char *required_type,
+ unsigned long *size,
+ unsigned char *actual_sha1_return)
+{
+ char type[20];
+ void *buffer;
+ unsigned long isize;
+ unsigned char actual_sha1[20];
+
+ memcpy(actual_sha1, sha1, 20);
+ while (1) {
+ int ref_length = -1;
+ const char *ref_type = NULL;
+
+ buffer = read_sha1_file(actual_sha1, type, &isize);
+ if (!buffer)
+ return NULL;
+ if (!strcmp(type, required_type)) {
+ *size = isize;
+ if (actual_sha1_return)
+ memcpy(actual_sha1_return, actual_sha1, 20);
+ return buffer;
+ }
+ /* Handle references */
+ else if (!strcmp(type, "commit"))
+ ref_type = "tree ";
+ else if (!strcmp(type, "tag"))
+ ref_type = "object ";
+ else {
+ free(buffer);
+ return NULL;
+ }
+ ref_length = strlen(ref_type);
+
+ if (memcmp(buffer, ref_type, ref_length) ||
+ get_sha1_hex(buffer + ref_length, actual_sha1)) {
+ free(buffer);
+ return NULL;
+ }
+ /* Now we have the ID of the referred-to object in
+ * actual_sha1. Check again. */
+ }
+}
+
+int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)