summaryrefslogtreecommitdiff
path: root/src/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.c')
-rw-r--r--src/object.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/object.c b/src/object.c
index c53a3acae..c9809c52a 100644
--- a/src/object.c
+++ b/src/object.c
@@ -209,6 +209,125 @@ void git_object__source_close(git_object *object)
}
}
+static int create_object(git_object **object_out, git_otype type)
+{
+ git_object *object = NULL;
+
+ assert(object_out);
+
+ *object_out = NULL;
+
+ switch (type) {
+ case GIT_OBJ_COMMIT:
+ case GIT_OBJ_TAG:
+ case GIT_OBJ_BLOB:
+ object = git__malloc(git_object__size(type));
+ if (object == NULL)
+ return GIT_ENOMEM;
+ memset(object, 0x0, git_object__size(type));
+ break;
+
+ case GIT_OBJ_TREE:
+ object = (git_object *)git_tree__new();
+ if (object == NULL)
+ return GIT_ENOMEM;
+ break;
+
+ default:
+ return GIT_EINVALIDTYPE;
+ }
+
+ *object_out = object;
+ return GIT_SUCCESS;
+}
+
+int git_object_new(git_object **object_out, git_repository *repo, git_otype type)
+{
+ git_object *object = NULL;
+ int error;
+
+ assert(object_out && repo);
+
+ if ((error = create_object(&object, type)) < GIT_SUCCESS)
+ return error;
+
+ object->repo = repo;
+ object->in_memory = 1;
+ object->modified = 1;
+
+ object->source.raw.type = type;
+
+ *object_out = object;
+ return GIT_SUCCESS;
+}
+
+int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_otype type)
+{
+ git_object *object = NULL;
+ git_rawobj obj_file;
+ int error = GIT_SUCCESS;
+
+ assert(repo && object_out && id);
+
+ object = git_hashtable_lookup(repo->objects, id);
+ if (object != NULL) {
+ *object_out = object;
+ return GIT_SUCCESS;
+ }
+
+ error = git_odb_read(&obj_file, repo->db, id);
+ if (error < GIT_SUCCESS)
+ return error;
+
+ if (type != GIT_OBJ_ANY && type != obj_file.type) {
+ git_rawobj_close(&obj_file);
+ return GIT_EINVALIDTYPE;
+ }
+
+ type = obj_file.type;
+
+ if ((error = create_object(&object, type)) < GIT_SUCCESS)
+ return error;
+
+ /* Initialize parent object */
+ git_oid_cpy(&object->id, id);
+ object->repo = repo;
+ memcpy(&object->source.raw, &obj_file, sizeof(git_rawobj));
+ object->source.open = 1;
+
+ switch (type) {
+ case GIT_OBJ_COMMIT:
+ error = git_commit__parse((git_commit *)object);
+ break;
+
+ case GIT_OBJ_TREE:
+ error = git_tree__parse((git_tree *)object);
+ break;
+
+ case GIT_OBJ_TAG:
+ error = git_tag__parse((git_tag *)object);
+ break;
+
+ case GIT_OBJ_BLOB:
+ error = git_blob__parse((git_blob *)object);
+ break;
+
+ default:
+ break;
+ }
+
+ if (error < GIT_SUCCESS) {
+ git_object_free(object);
+ return error;
+ }
+
+ git_object__source_close(object);
+ git_hashtable_insert(repo->objects, &object->id, object);
+
+ *object_out = object;
+ return GIT_SUCCESS;
+}
+
int git_object_write(git_object *object)
{
int error;