void git_object_free(git_object *object) { if (object == NULL) return; git_object__source_close(object); git_hashtable_remove(object->repo->objects, &object->id); switch (object->source.raw.type) { case GIT_OBJ_COMMIT: git_commit__free((git_commit *)object); break; case GIT_OBJ_TREE: git_tree__free((git_tree *)object); break; case GIT_OBJ_TAG: git_tag__free((git_tag *)object); break; case GIT_OBJ_BLOB: git_blob__free((git_blob *)object); break; default: free(object); break; } }
static int write_back(git_object *object) { int error; git_oid new_id; assert(object); assert(object->source.open); assert(object->modified); object->source.raw.len = object->source.written_bytes; if ((error = git_odb_write(&new_id, object->repo->db, &object->source.raw)) < GIT_SUCCESS) return error; if (!object->in_memory) git_hashtable_remove(object->repo->objects, &object->id); git_oid_cpy(&object->id, &new_id); git_hashtable_insert(object->repo->objects, &object->id, object); object->source.write_ptr = NULL; object->source.written_bytes = 0; object->modified = 0; object->in_memory = 0; git_object__source_close(object); return GIT_SUCCESS; }
void git_object__free(git_object *object) { assert(object); git_object__source_close(object); switch (object->source.raw.type) { case GIT_OBJ_COMMIT: git_commit__free((git_commit *)object); break; case GIT_OBJ_TREE: git_tree__free((git_tree *)object); break; case GIT_OBJ_TAG: git_tag__free((git_tag *)object); break; case GIT_OBJ_BLOB: git_blob__free((git_blob *)object); break; default: free(object); break; } }
static void prepare_write(git_object *object) { if (object->source.write_ptr != NULL || object->source.open) git_object__source_close(object); /* TODO: proper size calculation */ object->source.raw.data = git__malloc(OBJECT_BASE_SIZE); object->source.raw.len = OBJECT_BASE_SIZE; object->source.write_ptr = object->source.raw.data; object->source.written_bytes = 0; object->source.open = 1; }
int git_object__source_open(git_object *object) { int error; assert(object && !object->in_memory); if (object->source.open) git_object__source_close(object); error = git_odb_read(&object->source.raw, object->repo->db, &object->id); if (error < GIT_SUCCESS) return error; object->source.open = 1; return GIT_SUCCESS; }
int git_commit__parse_full(git_commit *commit) { int error; if (commit->full_parse) return GIT_SUCCESS; if ((error = git_object__source_open((git_object *)commit)) < GIT_SUCCESS) return error; error = commit_parse_buffer(commit, commit->object.source.raw.data, commit->object.source.raw.len, COMMIT_FULL_PARSE); git_object__source_close((git_object *)commit); commit->full_parse = 1; return error; }
int git_object_write(git_object *object) { int error; git_odb_source *source; assert(object); if (object->modified == 0) return GIT_SUCCESS; prepare_write(object); source = &object->source; switch (source->raw.type) { case GIT_OBJ_COMMIT: error = git_commit__writeback((git_commit *)object, source); break; case GIT_OBJ_TREE: error = git_tree__writeback((git_tree *)object, source); break; case GIT_OBJ_TAG: error = git_tag__writeback((git_tag *)object, source); break; case GIT_OBJ_BLOB: error = git_blob__writeback((git_blob *)object, source); break; default: error = GIT_ERROR; break; } if (error < GIT_SUCCESS) { git_object__source_close(object); return error; } return write_back(object); }
int git_blob_set_rawcontent(git_blob *blob, const void *buffer, size_t len) { assert(blob && buffer); blob->object.modified = 1; git_object__source_close((git_object *)blob); if (blob->content.data != NULL) gitfo_free_buf(&blob->content); blob->content.data = git__malloc(len); blob->content.len = len; if (blob->content.data == NULL) return GIT_ENOMEM; memcpy(blob->content.data, buffer, len); 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; GIT_OBJECT_INCREF(repo, 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); GIT_OBJECT_INCREF(repo, object); *object_out = object; return GIT_SUCCESS; }