Add git-for-each-ref: helper for language bindings
[git/git.git] / object.c
index 9281300..de244e2 100644 (file)
--- a/object.c
+++ b/object.c
@@ -138,42 +138,56 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
        return obj;
 }
 
+struct object *parse_object_buffer(const unsigned char *sha1, const char *type, unsigned long size, void *buffer, int *eaten_p)
+{
+       struct object *obj;
+       int eaten = 0;
+
+       if (!strcmp(type, blob_type)) {
+               struct blob *blob = lookup_blob(sha1);
+               parse_blob_buffer(blob, buffer, size);
+               obj = &blob->object;
+       } else if (!strcmp(type, tree_type)) {
+               struct tree *tree = lookup_tree(sha1);
+               obj = &tree->object;
+               if (!tree->object.parsed) {
+                       parse_tree_buffer(tree, buffer, size);
+                       eaten = 1;
+               }
+       } else if (!strcmp(type, commit_type)) {
+               struct commit *commit = lookup_commit(sha1);
+               parse_commit_buffer(commit, buffer, size);
+               if (!commit->buffer) {
+                       commit->buffer = buffer;
+                       eaten = 1;
+               }
+               obj = &commit->object;
+       } else if (!strcmp(type, tag_type)) {
+               struct tag *tag = lookup_tag(sha1);
+               parse_tag_buffer(tag, buffer, size);
+               obj = &tag->object;
+       } else {
+               obj = NULL;
+       }
+       *eaten_p = eaten;
+       return obj;
+}
+
 struct object *parse_object(const unsigned char *sha1)
 {
        unsigned long size;
        char type[20];
+       int eaten;
        void *buffer = read_sha1_file(sha1, type, &size);
+
        if (buffer) {
                struct object *obj;
                if (check_sha1_signature(sha1, buffer, size, type) < 0)
                        printf("sha1 mismatch %s\n", sha1_to_hex(sha1));
-               if (!strcmp(type, blob_type)) {
-                       struct blob *blob = lookup_blob(sha1);
-                       parse_blob_buffer(blob, buffer, size);
-                       obj = &blob->object;
-               } else if (!strcmp(type, tree_type)) {
-                       struct tree *tree = lookup_tree(sha1);
-                       obj = &tree->object;
-                       if (!tree->object.parsed) {
-                               parse_tree_buffer(tree, buffer, size);
-                               buffer = NULL;
-                       }
-               } else if (!strcmp(type, commit_type)) {
-                       struct commit *commit = lookup_commit(sha1);
-                       parse_commit_buffer(commit, buffer, size);
-                       if (!commit->buffer) {
-                               commit->buffer = buffer;
-                               buffer = NULL;
-                       }
-                       obj = &commit->object;
-               } else if (!strcmp(type, tag_type)) {
-                       struct tag *tag = lookup_tag(sha1);
-                       parse_tag_buffer(tag, buffer, size);
-                       obj = &tag->object;
-               } else {
-                       obj = NULL;
-               }
-               free(buffer);
+
+               obj = parse_object_buffer(sha1, type, size, buffer, &eaten);
+               if (!eaten)
+                       free(buffer);
                return obj;
        }
        return NULL;