static void assert_commit_parses(const char *data, size_t datalen, const char *expected_treeid, const char *expected_author, const char *expected_committer, const char *expected_encoding, const char *expected_message, size_t expected_parents) { git_commit *commit; if (!datalen) datalen = strlen(data); cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT)); if (expected_author) { git_signature *author; cl_git_pass(git_signature_from_buffer(&author, expected_author)); cl_assert(git_signature__equal(author, commit->author)); cl_assert_equal_s(author->name, commit->author->name); cl_assert_equal_s(author->email, commit->author->email); cl_assert_equal_i(author->when.time, commit->author->when.time); cl_assert_equal_i(author->when.offset, commit->author->when.offset); cl_assert_equal_i(author->when.sign, commit->author->when.sign); git_signature_free(author); } if (expected_committer) { git_signature *committer; cl_git_pass(git_signature_from_buffer(&committer, expected_committer)); cl_assert_equal_s(committer->name, commit->committer->name); cl_assert_equal_s(committer->email, commit->committer->email); cl_assert_equal_i(committer->when.time, commit->committer->when.time); cl_assert_equal_i(committer->when.offset, commit->committer->when.offset); cl_assert_equal_i(committer->when.sign, commit->committer->when.sign); git_signature_free(committer); } if (expected_encoding) cl_assert_equal_s(commit->message_encoding, expected_encoding); else cl_assert_equal_p(commit->message_encoding, NULL); if (expected_message) cl_assert_equal_s(commit->raw_message, expected_message); else cl_assert_equal_p(commit->message_encoding, NULL); if (expected_treeid) { git_oid tree_oid; cl_git_pass(git_oid_fromstr(&tree_oid, expected_treeid)); cl_assert_equal_oid(&tree_oid, &commit->tree_id); } cl_assert_equal_i(commit->parent_ids.size, expected_parents); git_object__free(&commit->object); }
int git_object__from_odb_object( git_object **object_out, git_repository *repo, git_odb_object *odb_obj, git_otype type) { int error; git_object *object = NULL; if (type != GIT_OBJ_ANY && type != odb_obj->raw.type) { giterr_set(GITERR_INVALID, "The requested type does not match the type in the ODB"); return GIT_ENOTFOUND; } type = odb_obj->raw.type; if ((error = create_object(&object, type)) < 0) return error; /* Initialize parent object */ git_oid_cpy(&object->cached.oid, &odb_obj->cached.oid); object->repo = repo; switch (type) { case GIT_OBJ_COMMIT: error = git_commit__parse((git_commit *)object, odb_obj); break; case GIT_OBJ_TREE: error = git_tree__parse((git_tree *)object, odb_obj); break; case GIT_OBJ_TAG: error = git_tag__parse((git_tag *)object, odb_obj); break; case GIT_OBJ_BLOB: error = git_blob__parse((git_blob *)object, odb_obj); break; default: break; } if (error < 0) git_object__free(object); else *object_out = git_cache_try_store(&repo->objects, object); return error; }
void git_object_close(git_object *object) { if (object == NULL) return; if (--object->refcount <= 0) { if (object->repo != NULL) { if (object->in_memory) { int idx = git_vector_search(&object->repo->memory_objects, object); git_vector_remove(&object->repo->memory_objects, idx); } else { git_hashtable_remove(object->repo->objects, &object->id); } } git_object__free(object); } }
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; }