commit 15a949835c36ceb581fc115aff744dbb30b12918 from: Stefan Sperling date: Sun Dec 23 13:48:47 2018 UTC remove struct got_object from public library API commit - 5767055949fa7c49469611a514c2f4e3ae77c5e1 commit + 15a949835c36ceb581fc115aff744dbb30b12918 blob - 9ca1e6c6f71588c3806a731999ac91937c63c1f2 blob + 4f7d23771ac7850de8807514c25be47cc3ceb7fc --- got/got.c +++ got/got.c @@ -416,9 +416,9 @@ print_commit(struct got_commit_object *commit, struct } static const struct got_error * -print_commits(struct got_object *root_obj, struct got_object_id *root_id, - struct got_repository *repo, char *path, int show_patch, int diff_context, - int limit, int first_parent_traversal) +print_commits(struct got_object_id *root_id, struct got_repository *repo, + char *path, int show_patch, int diff_context, int limit, + int first_parent_traversal) { const struct got_error *err; struct got_commit_graph *graph; @@ -480,8 +480,8 @@ cmd_log(int argc, char *argv[]) { const struct got_error *error; struct got_repository *repo = NULL; + struct got_commit_object *commit = NULL; struct got_object_id *id = NULL; - struct got_object *obj = NULL; char *repo_path = NULL, *path = NULL, *cwd = NULL, *in_repo_path = NULL; char *start_commit = NULL; int diff_context = 3, ch; @@ -565,7 +565,7 @@ cmd_log(int argc, char *argv[]) got_ref_close(head_ref); if (error != NULL) return error; - error = got_object_open(&obj, repo, id); + error = got_object_open_as_commit(&commit, repo, id); } else { struct got_reference *ref; error = got_ref_open(&ref, repo, start_commit); @@ -574,26 +574,19 @@ cmd_log(int argc, char *argv[]) got_ref_close(ref); if (error != NULL) return error; - error = got_object_open(&obj, repo, id); + error = got_object_open_as_commit(&commit, repo, id); if (error != NULL) return error; } - if (obj == NULL) { - error = got_object_open_by_id_str(&obj, repo, + if (commit == NULL) { + error = got_object_resolve_id_str(&id, repo, start_commit); if (error != NULL) return error; - id = got_object_id_dup(got_object_get_id(obj)); - if (id == NULL) - error = got_error_from_errno(); } } if (error != NULL) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) { - error = got_error(GOT_ERR_OBJ_TYPE); - goto done; - } error = got_repo_map_path(&in_repo_path, repo, path, 1); if (error != NULL) @@ -603,14 +596,12 @@ cmd_log(int argc, char *argv[]) path = in_repo_path; } - error = print_commits(obj, id, repo, path, show_patch, + error = print_commits(id, repo, path, show_patch, diff_context, limit, first_parent_traversal); done: free(path); free(repo_path); free(cwd); - if (obj) - got_object_close(obj); free(id); if (repo) { const struct got_error *repo_error; @@ -634,9 +625,10 @@ cmd_diff(int argc, char *argv[]) { const struct got_error *error; struct got_repository *repo = NULL; - struct got_object *obj1 = NULL, *obj2 = NULL; char *repo_path = NULL; - char *obj_id_str1 = NULL, *obj_id_str2 = NULL; + struct got_object_id *id1 = NULL, *id2 = NULL; + char *id_str1 = NULL, *id_str2 = NULL; + int type1, type2; int diff_context = 3, ch; const char *errstr; @@ -668,14 +660,14 @@ cmd_diff(int argc, char *argv[]) repo_path = getcwd(NULL, 0); if (repo_path == NULL) return got_error_from_errno(); - obj_id_str1 = argv[0]; - obj_id_str2 = argv[1]; + id_str1 = argv[0]; + id_str2 = argv[1]; } else if (argc == 3) { repo_path = realpath(argv[0], NULL); if (repo_path == NULL) return got_error_from_errno(); - obj_id_str1 = argv[1]; - obj_id_str2 = argv[2]; + id_str1 = argv[1]; + id_str2 = argv[2]; } else usage_diff(); @@ -684,32 +676,40 @@ cmd_diff(int argc, char *argv[]) if (error != NULL) goto done; - error = got_object_open_by_id_str(&obj1, repo, obj_id_str1); + error = got_object_resolve_id_str(&id1, repo, id_str1); if (error) goto done; - error = got_object_open_by_id_str(&obj2, repo, obj_id_str2); + error = got_object_resolve_id_str(&id2, repo, id_str2); if (error) goto done; - if (got_object_get_type(obj1) != got_object_get_type(obj2)) { + error = got_object_get_type(&type1, repo, id1); + if (error) + goto done; + + error = got_object_get_type(&type2, repo, id2); + if (error) + goto done; + + if (type1 != type2) { error = got_error(GOT_ERR_OBJ_TYPE); goto done; } - switch (got_object_get_type(obj1)) { + switch (type1) { case GOT_OBJ_TYPE_BLOB: - error = got_diff_objects_as_blobs(obj1, obj2, NULL, NULL, + error = got_diff_objects_as_blobs(id1, id2, NULL, NULL, diff_context, repo, stdout); break; case GOT_OBJ_TYPE_TREE: - error = got_diff_objects_as_trees(obj1, obj2, "", "", + error = got_diff_objects_as_trees(id1, id2, "", "", diff_context, repo, stdout); break; case GOT_OBJ_TYPE_COMMIT: - printf("diff %s %s\n", obj_id_str1 ? obj_id_str1 : "/dev/null", - obj_id_str2); - error = got_diff_objects_as_commits(obj1, obj2, diff_context, + printf("diff %s %s\n", id_str1 ? id_str1 : "/dev/null", + id_str2); + error = got_diff_objects_as_commits(id1, id2, diff_context, repo, stdout); break; default: @@ -717,10 +717,8 @@ cmd_diff(int argc, char *argv[]) } done: - if (obj1) - got_object_close(obj1); - if (obj2) - got_object_close(obj2); + free(id1); + free(id2); if (repo) { const struct got_error *repo_error; repo_error = got_repo_close(repo); @@ -809,14 +807,10 @@ cmd_blame(int argc, char *argv[]) if (error != NULL) goto done; } else { - struct got_object *obj; - error = got_object_open_by_id_str(&obj, repo, commit_id_str); + error = got_object_resolve_id_str(&commit_id, repo, + commit_id_str); if (error != NULL) goto done; - commit_id = got_object_id_dup(got_object_get_id(obj)); - if (commit_id == NULL) - error = got_error_from_errno(); - got_object_close(obj); } error = got_blame(in_repo_path, commit_id, repo, stdout); @@ -969,14 +963,10 @@ cmd_tree(int argc, char *argv[]) if (error != NULL) goto done; } else { - struct got_object *obj; - error = got_object_open_by_id_str(&obj, repo, commit_id_str); + error = got_object_resolve_id_str(&commit_id, repo, + commit_id_str); if (error != NULL) goto done; - commit_id = got_object_id_dup(got_object_get_id(obj)); - if (commit_id == NULL) - error = got_error_from_errno(); - got_object_close(obj); } error = print_tree(in_repo_path, commit_id, show_ids, repo); blob - a817a1eabed26be1253b9c113d07a6679a76376b blob + 01e0ac643704c52d2defe4e6e2bffdc0b8b5f8e4 --- include/got_diff.h +++ include/got_diff.h @@ -42,8 +42,8 @@ const struct got_error *got_diff_tree(struct got_tree_ * The number of context lines to show in the diff must be specified as well. * Write unified diff text to the provided output FILE. */ -const struct got_error *got_diff_objects_as_blobs(struct got_object *, - struct got_object *, const char *, const char *, int, +const struct got_error *got_diff_objects_as_blobs(struct got_object_id *, + struct got_object_id *, const char *, const char *, int, struct got_repository *, FILE *); /* @@ -53,15 +53,15 @@ const struct got_error *got_diff_objects_as_blobs(stru * The number of context lines to show in diffs must be specified. * Write unified diff text to the provided output FILE. */ -const struct got_error *got_diff_objects_as_trees(struct got_object *, - struct got_object *, char *, char *, int, struct got_repository *, FILE *); +const struct got_error *got_diff_objects_as_trees(struct got_object_id *, + struct got_object_id *, char *, char *, int, struct got_repository *, FILE *); /* * Diff two objects, assuming both objects are commits. * The number of context lines to show in diffs must be specified. * Write unified diff text to the provided output FILE. */ -const struct got_error *got_diff_objects_as_commits(struct got_object *, - struct got_object *, int, struct got_repository *, FILE *); +const struct got_error *got_diff_objects_as_commits(struct got_object_id *, + struct got_object_id *, int, struct got_repository *, FILE *); #define GOT_DIFF_MAX_CONTEXT 64 blob - 17bb86dfcb85bb18275fcb5dea4c782859da9699 blob + 514355200012b8f3306f409556261bae2b9822f8 --- include/got_object.h +++ include/got_object.h @@ -46,8 +46,7 @@ const struct got_error *got_object_qid_alloc(struct go struct got_object_id *); void got_object_qid_free(struct got_object_qid *); -/* A generic object. Used as a handle which holds an ID and an object type. */ -struct got_object; +/* Object types. */ #define GOT_OBJ_TYPE_COMMIT 1 #define GOT_OBJ_TYPE_TREE 2 #define GOT_OBJ_TYPE_BLOB 3 @@ -77,19 +76,6 @@ int got_object_id_cmp(const struct got_object_id *, struct got_object_id *got_object_id_dup(struct got_object_id *); /* - * Get a newly allocated copy of an object's ID. - * The caller must treat the ID as read-only and must not call free(3) on it. - * Use got_object_id_dup() to get a writable copy. - */ -struct got_object_id *got_object_get_id(struct got_object *); - -/* - * Get a newly allocated copy of an object's ID string. - * The caller should dispose of it with free(3). - */ -const struct got_error *got_object_get_id_str(char **, struct got_object *); - -/* * Get a newly allocated ID of the object which resides at the specified * path in the tree of the specified commit. * The caller should dispose of it with free(3). @@ -102,35 +88,26 @@ got_object_id_by_path(struct got_object_id **, struct * Obtain the type of an object. * Returns one of the GOT_OBJ_TYPE_x values (see above). */ -int got_object_get_type(struct got_object *); +const struct got_error *got_object_get_type(int *, struct got_repository *, + struct got_object_id *); /* - * Attempt to open the object in a repository with the provided ID. - * Caller must dispose of it with got_object_close(). + * Attempt to resolve the textual representation of an object ID + * to the ID of an existing object in the repository. + * The caller should dispose of the ID with free(3). */ -const struct got_error *got_object_open(struct got_object **, - struct got_repository *, struct got_object_id *); +const struct got_error * +got_object_resolve_id_str(struct got_object_id **, struct got_repository *, + const char *); /* - * Attempt to map the provided ID string to an object ID and then - * attempt to open the object in a repository with this ID. - * The form of an ID string depends on the hash function used by the - * repository format (currently SHA1). - * Caller must dispose of the object with got_object_close(). - */ -const struct got_error *got_object_open_by_id_str(struct got_object **, - struct got_repository *, const char *); - -/* Dispose of an object. */ -void got_object_close(struct got_object *); - -/* * Attempt to open a commit object in a repository. * The provided object must be of type GOT_OBJ_TYPE_COMMIT. * The caller must dispose of the commit with got_object_commit_close(). */ -const struct got_error *got_object_commit_open(struct got_commit_object **, - struct got_repository *, struct got_object *); +const struct got_error * +got_object_open_as_commit(struct got_commit_object **, + struct got_repository *, struct got_object_id *); /* Dispose of a commit object. */ void got_object_commit_close(struct got_commit_object *); @@ -171,8 +148,9 @@ const char *got_object_commit_get_logmsg(struct got_co * The provided object must be of type GOT_OBJ_TYPE_TREE. * The caller must dispose of the tree with got_object_tree_close(). */ -const struct got_error *got_object_tree_open(struct got_tree_object **, - struct got_repository *, struct got_object *); +const struct got_error * +got_object_open_as_tree(struct got_tree_object **, + struct got_repository *, struct got_object_id *); /* Dispose of a tree object. */ void got_object_tree_close(struct got_tree_object *); @@ -196,8 +174,9 @@ const struct got_error *got_object_tree_path_changed(i * The size_t argument specifies the block size of an associated read buffer. * The caller must dispose of the blob with got_object_blob_close(). */ -const struct got_error *got_object_blob_open(struct got_blob_object **, - struct got_repository *, struct got_object *, size_t); +const struct got_error * +got_object_open_as_blob(struct got_blob_object **, + struct got_repository *, struct got_object_id *, size_t); /* Dispose of a blob object. */ void got_object_blob_close(struct got_blob_object *); @@ -246,23 +225,11 @@ const struct got_error *got_object_blob_dump_to_file(s * The provided object must be of type GOT_OBJ_TYPE_TAG. * The caller must dispose of the tree with got_object_tag_close(). */ -const struct got_error *got_object_tag_open(struct got_tag_object **, - struct got_repository *, struct got_object *); +const struct got_error *got_object_open_as_tag(struct got_tag_object **, + struct got_repository *, struct got_object_id *); /* Dispose of a tag object. */ void got_object_tag_close(struct got_tag_object *); -const struct got_error * -got_object_open_as_commit(struct got_commit_object **, - struct got_repository *, struct got_object_id *); -const struct got_error * -got_object_open_as_tree(struct got_tree_object **, - struct got_repository *, struct got_object_id *); -const struct got_error * -got_object_open_as_blob(struct got_blob_object **, - struct got_repository *, struct got_object_id *, size_t); -const struct got_error *got_object_open_as_tag(struct got_tag_object **, - struct got_repository *, struct got_object_id *); - const struct got_error *got_object_commit_add_parent(struct got_commit_object *, const char *); blob - 977d7f578441bc9814edefb94eb8001344b09deb blob + e8e4e2b505da78e54c8c0d88c7df21b3aee29442 --- lib/blame.c +++ lib/blame.c @@ -203,7 +203,7 @@ blame_commit(struct got_blame *blame, struct got_objec if (err) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) { + if (obj->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -228,7 +228,7 @@ blame_commit(struct got_blame *blame, struct got_objec if (err) goto done; - if (got_object_get_type(pobj) != GOT_OBJ_TYPE_BLOB) { + if (pobj->type != GOT_OBJ_TYPE_BLOB) { /* * Encountered a non-blob at the path (probably a tree). * Blob's history began in previous commit. @@ -309,7 +309,7 @@ blame_open(struct got_blame **blamep, const char *path if (err) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) { + if (obj->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } blob - 40c9a34cc71199d0d450d917eecec341f671beec blob + 874c7535c3108bccd764b3e2e206e12189b9aa97 --- lib/delta.c +++ lib/delta.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "got_error.h" #include "got_repository.h" @@ -31,6 +32,7 @@ #include "got_lib_delta.h" #include "got_lib_path.h" #include "got_lib_inflate.h" +#include "got_lib_object.h" #ifndef MIN #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) blob - 9af8a526beb32027acfb0c3d1027c8e543a961be blob + 29d72606d8f28dd96deb06d37531e5db5e1c99ab --- lib/diff.c +++ lib/diff.c @@ -32,6 +32,9 @@ #include "got_lib_diff.h" #include "got_lib_path.h" +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" static const struct got_error * diff_blobs(struct got_blob_object *blob1, struct got_blob_object *blob2, @@ -205,7 +208,7 @@ diff_modified_blob(struct got_object_id *id1, struct g err = got_object_open(&obj1, repo, id1); if (err) return err; - if (got_object_get_type(obj1) != GOT_OBJ_TYPE_BLOB) { + if (obj1->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -213,7 +216,7 @@ diff_modified_blob(struct got_object_id *id1, struct g err = got_object_open(&obj2, repo, id2); if (err) goto done; - if (got_object_get_type(obj2) != GOT_OBJ_TYPE_BLOB) { + if (obj2->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; } @@ -276,7 +279,7 @@ diff_added_tree(struct got_object_id *id, const char * if (err) goto done; - if (got_object_get_type(treeobj) != GOT_OBJ_TYPE_TREE) { + if (treeobj->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -311,7 +314,7 @@ diff_modified_tree(struct got_object_id *id1, struct g if (err) goto done; - if (got_object_get_type(treeobj1) != GOT_OBJ_TYPE_TREE) { + if (treeobj1->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -320,7 +323,7 @@ diff_modified_tree(struct got_object_id *id1, struct g if (err) goto done; - if (got_object_get_type(treeobj2) != GOT_OBJ_TYPE_TREE) { + if (treeobj2->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -360,7 +363,7 @@ diff_deleted_tree(struct got_object_id *id, const char if (err) goto done; - if (got_object_get_type(treeobj) != GOT_OBJ_TYPE_TREE) { + if (treeobj->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -526,23 +529,23 @@ got_diff_tree(struct got_tree_object *tree1, struct go } const struct got_error * -got_diff_objects_as_blobs(struct got_object *obj1, struct got_object *obj2, +got_diff_objects_as_blobs(struct got_object_id *id1, struct got_object_id *id2, const char *label1, const char *label2, int diff_context, struct got_repository *repo, FILE *outfile) { const struct got_error *err; struct got_blob_object *blob1 = NULL, *blob2 = NULL; - if (obj1 == NULL && obj2 == NULL) + if (id1 == NULL && id2 == NULL) return got_error(GOT_ERR_NO_OBJ); - if (obj1) { - err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (id1) { + err = got_object_open_as_blob(&blob1, repo, id1, 8192); if (err) goto done; } - if (obj2) { - err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (id2) { + err = got_object_open_as_blob(&blob2, repo, id2, 8192); if (err) goto done; } @@ -557,23 +560,23 @@ done: } const struct got_error * -got_diff_objects_as_trees(struct got_object *obj1, struct got_object *obj2, +got_diff_objects_as_trees(struct got_object_id *id1, struct got_object_id *id2, char *label1, char *label2, int diff_context, struct got_repository *repo, FILE *outfile) { const struct got_error *err; struct got_tree_object *tree1 = NULL, *tree2 = NULL; - if (obj1 == NULL && obj2 == NULL) + if (id1 == NULL && id2 == NULL) return got_error(GOT_ERR_NO_OBJ); - if (obj1) { - err = got_object_tree_open(&tree1, repo, obj1); + if (id1) { + err = got_object_open_as_tree(&tree1, repo, id1); if (err) goto done; } - if (obj2) { - err = got_object_tree_open(&tree2, repo, obj2); + if (id2) { + err = got_object_open_as_tree(&tree2, repo, id2); if (err) goto done; } @@ -588,41 +591,31 @@ done: } const struct got_error * -got_diff_objects_as_commits(struct got_object *obj1, struct got_object *obj2, - int diff_context, struct got_repository *repo, FILE *outfile) +got_diff_objects_as_commits(struct got_object_id *id1, + struct got_object_id *id2, int diff_context, + struct got_repository *repo, FILE *outfile) { const struct got_error *err; struct got_commit_object *commit1 = NULL, *commit2 = NULL; - struct got_object *tree_obj1 = NULL, *tree_obj2 = NULL; - if (obj2 == NULL) + if (id2 == NULL) return got_error(GOT_ERR_NO_OBJ); - if (obj1) { - err = got_object_commit_open(&commit1, repo, obj1); + if (id1) { + err = got_object_open_as_commit(&commit1, repo, id1); if (err) goto done; - err = got_object_open(&tree_obj1, repo, - got_object_commit_get_tree_id(commit1)); - if (err) - goto done; } - err = got_object_commit_open(&commit2, repo, obj2); + err = got_object_open_as_commit(&commit2, repo, id2); if (err) goto done; - err = got_object_open(&tree_obj2, repo, - got_object_commit_get_tree_id(commit2)); - if (err) - goto done; - err = got_diff_objects_as_trees(tree_obj1, tree_obj2, "", "", - diff_context, repo, outfile); + err = got_diff_objects_as_trees( + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, repo, + outfile); done: - if (tree_obj1) - got_object_close(tree_obj1); - if (tree_obj2) - got_object_close(tree_obj2); if (commit1) got_object_commit_close(commit1); if (commit2) blob - 7bcbdfd39b328a04433e376dbf7471f0e48c4482 blob + 87f0ab97317782cc93168da4c232f27d71c14646 --- lib/got_lib_object.h +++ lib/got_lib_object.h @@ -20,6 +20,7 @@ struct got_object_id { struct got_object { int type; + int flags; #define GOT_OBJ_FLAG_PACKED 0x01 #define GOT_OBJ_FLAG_DELTIFIED 0x02 @@ -73,3 +74,19 @@ struct got_tag_object { char *tagmsg; int refcnt; /* > 0 if open and/or cached */ }; + +struct got_object_id *got_object_get_id(struct got_object *); +const struct got_error *got_object_get_id_str(char **, struct got_object *); +const struct got_error *got_object_open(struct got_object **, + struct got_repository *, struct got_object_id *); +const struct got_error *got_object_open_by_id_str(struct got_object **, + struct got_repository *, const char *); +void got_object_close(struct got_object *); +const struct got_error *got_object_commit_open(struct got_commit_object **, + struct got_repository *, struct got_object *); +const struct got_error *got_object_tree_open(struct got_tree_object **, + struct got_repository *, struct got_object *); +const struct got_error *got_object_blob_open(struct got_blob_object **, + struct got_repository *, struct got_object *, size_t); +const struct got_error *got_object_tag_open(struct got_tag_object **, + struct got_repository *, struct got_object *); blob - d8eaa0694dfff1236a766498a23852ee8d234ee3 blob + 5abbe4fb9abe5e54f998a07a753ac660a1229408 --- lib/object.c +++ lib/object.c @@ -42,7 +42,6 @@ #include "got_lib_sha1.h" #include "got_lib_delta.h" -#include "got_lib_pack.h" #include "got_lib_path.h" #include "got_lib_inflate.h" #include "got_lib_object.h" @@ -50,6 +49,7 @@ #include "got_lib_object_idcache.h" #include "got_lib_object_cache.h" #include "got_lib_object_parse.h" +#include "got_lib_pack.h" #include "got_lib_repository.h" #ifndef MIN @@ -80,22 +80,31 @@ got_object_get_id_str(char **outbuf, struct got_object return got_object_id_str(outbuf, &obj->id); } -int -got_object_get_type(struct got_object *obj) +const struct got_error * +got_object_get_type(int *type, struct got_repository *repo, + struct got_object_id *id) { + const struct got_error *err = NULL; + struct got_object *obj; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + switch (obj->type) { case GOT_OBJ_TYPE_COMMIT: case GOT_OBJ_TYPE_TREE: case GOT_OBJ_TYPE_BLOB: case GOT_OBJ_TYPE_TAG: - return obj->type; + *type = obj->type; + break; default: - abort(); + err = got_error(GOT_ERR_OBJ_TYPE); break; } - /* not reached */ - return 0; + got_object_close(obj); + return err; } static const struct got_error * @@ -263,6 +272,25 @@ got_object_open_by_id_str(struct got_object **obj, str return got_error(GOT_ERR_BAD_OBJ_ID_STR); return got_object_open(obj, repo, &id); +} + +const struct got_error * +got_object_resolve_id_str(struct got_object_id **id, + struct got_repository *repo, const char *id_str) +{ + const struct got_error *err = NULL; + struct got_object *obj; + + err = got_object_open_by_id_str(&obj, repo, id_str); + if (err) + return err; + + *id = got_object_id_dup(got_object_get_id(obj)); + got_object_close(obj); + if (*id == NULL) + return got_error_from_errno(); + + return NULL; } static const struct got_error * @@ -326,7 +354,7 @@ got_object_open_as_commit(struct got_commit_object **c err = got_object_open(&obj, repo, id); if (err) return err; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) { + if (obj->type != GOT_OBJ_TYPE_COMMIT) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -425,7 +453,7 @@ got_object_open_as_tree(struct got_tree_object **tree, err = got_object_open(&obj, repo, id); if (err) return err; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_TREE) { + if (obj->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -612,7 +640,7 @@ got_object_open_as_blob(struct got_blob_object **blob, err = got_object_open(&obj, repo, id); if (err) return err; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) { + if (obj->type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -763,7 +791,7 @@ got_object_open_as_tag(struct got_tag_object **tag, err = got_object_open(&obj, repo, id); if (err) return err; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) { + if (obj->type != GOT_OBJ_TYPE_COMMIT) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } blob - edf8f8d3f1e2d5afcc0926bb3d6edead7609e66b blob + 21d3471c2b584757cf15d68aad56eb7edd8d3d02 --- lib/object_parse.c +++ lib/object_parse.c @@ -42,11 +42,11 @@ #include "got_lib_sha1.h" #include "got_lib_delta.h" -#include "got_lib_privsep.h" -#include "got_lib_pack.h" #include "got_lib_inflate.h" #include "got_lib_object.h" #include "got_lib_object_cache.h" +#include "got_lib_pack.h" +#include "got_lib_privsep.h" #include "got_lib_repository.h" #ifndef nitems blob - 6c51109b82fc94cdee67d253b305f39d6961fcad blob + 73190458ebaf7433d7caacf33a385c026139d5dd --- lib/pack.c +++ lib/pack.c @@ -37,12 +37,12 @@ #include "got_opentemp.h" #include "got_lib_sha1.h" -#include "got_lib_pack.h" #include "got_lib_path.h" #include "got_lib_delta.h" #include "got_lib_inflate.h" #include "got_lib_object.h" #include "got_lib_privsep.h" +#include "got_lib_pack.h" #ifndef nitems #define nitems(_a) (sizeof(_a) / sizeof((_a)[0])) blob - 20f110b3b35b2536e85df68f177a3d4dde90379c blob + d74ed85680084b8e192d10eb6f77ade5721e72f1 --- lib/worktree.c +++ lib/worktree.c @@ -509,7 +509,7 @@ tree_checkout_entry(struct got_worktree *worktree, progress_path += len; (*progress_cb)(progress_arg, progress_path); - switch (got_object_get_type(obj)) { + switch (obj->type) { case GOT_OBJ_TYPE_BLOB: if (strlen(worktree->path_prefix) >= strlen(path)) break; @@ -623,7 +623,7 @@ got_worktree_checkout_files(struct got_worktree *workt if (err) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) { + if (obj->type != GOT_OBJ_TYPE_COMMIT) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } @@ -637,7 +637,7 @@ got_worktree_checkout_files(struct got_worktree *workt if (err) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_TREE) { + if (obj->type != GOT_OBJ_TYPE_TREE) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } blob - 18bc93be414b53dfc38357b8bfab53aa7227ee28 blob + b06a8e52157c5f52dce914f374c258995ac0dcb8 --- regress/repository/repository_test.c +++ regress/repository/repository_test.c @@ -57,7 +57,7 @@ test_printf(char *fmt, ...) } static const struct got_error * -print_commit_object(struct got_object *, struct got_repository *); +print_commit_object(struct got_object_id *, struct got_repository *); static const struct got_error * print_parent_commits(struct got_commit_object *commit, @@ -66,18 +66,10 @@ print_parent_commits(struct got_commit_object *commit, const struct got_object_id_queue *parent_ids; struct got_object_qid *qid; const struct got_error *err = NULL; - struct got_object *obj; parent_ids = got_object_commit_get_parent_ids(commit); SIMPLEQ_FOREACH(qid, parent_ids, entry) { - err = got_object_open(&obj, repo, qid->id); - if (err != NULL) - return err; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) - err = got_error(GOT_ERR_OBJ_TYPE); - else - err = print_commit_object(obj, repo); - got_object_close(obj); + err = print_commit_object(qid->id, repo); if (err) break; } @@ -86,7 +78,7 @@ print_parent_commits(struct got_commit_object *commit, } static const struct got_error * -print_tree_object(struct got_object *obj, char *parent, +print_tree_object(struct got_object_id *id, char *parent, struct got_repository *repo) { struct got_tree_object *tree; @@ -94,13 +86,12 @@ print_tree_object(struct got_object *obj, char *parent struct got_tree_entry *te; const struct got_error *err; - err = got_object_tree_open(&tree, repo, obj); + err = got_object_open_as_tree(&tree, repo, id); if (err != NULL) return err; entries = got_object_tree_get_entries(tree); SIMPLEQ_FOREACH(te, &entries->head, entry) { - struct got_object *treeobj; char *next_parent; char *hex; @@ -116,30 +107,15 @@ print_tree_object(struct got_object *obj, char *parent test_printf("%s %s/%s\n", hex, parent, te->name); free(hex); - err = got_object_open(&treeobj, repo, te->id); - if (err != NULL) - break; - - if (got_object_get_type(treeobj) != GOT_OBJ_TYPE_TREE) { - err = got_error(GOT_ERR_OBJ_TYPE); - got_object_close(treeobj); - break; - } - if (asprintf(&next_parent, "%s/%s", parent, te->name) == -1) { err = got_error_from_errno(); - got_object_close(treeobj); break; } - err = print_tree_object(treeobj, next_parent, repo); + err = print_tree_object(te->id, next_parent, repo); free(next_parent); - if (err) { - got_object_close(treeobj); + if (err) break; - } - - got_object_close(treeobj); } got_object_tree_close(tree); @@ -147,22 +123,24 @@ print_tree_object(struct got_object *obj, char *parent } static const struct got_error * -print_commit_object(struct got_object *obj, struct got_repository *repo) +print_commit_object(struct got_object_id *id, struct got_repository *repo) { struct got_commit_object *commit; const struct got_object_id_queue *parent_ids; struct got_object_qid *qid; char *buf; const struct got_error *err; - struct got_object* treeobj; + int obj_type; - err = got_object_commit_open(&commit, repo, obj); + err = got_object_open_as_commit(&commit, repo, id); if (err) return err; - err = got_object_id_str(&buf, got_object_commit_get_tree_id(commit)); - if (err) + err = got_object_id_str(&buf, id); + if (err) { + got_object_commit_close(commit); return err; + } test_printf("tree: %s\n", buf); free(buf); test_printf("parent%s: ", @@ -170,8 +148,10 @@ print_commit_object(struct got_object *obj, struct got parent_ids = got_object_commit_get_parent_ids(commit); SIMPLEQ_FOREACH(qid, parent_ids, entry) { err = got_object_id_str(&buf, qid->id); - if (err) + if (err) { + got_object_commit_close(commit); return err; + } test_printf("%s\n", buf); free(buf); } @@ -179,15 +159,14 @@ print_commit_object(struct got_object *obj, struct got test_printf("committer: %s\n", got_object_commit_get_committer(commit)); test_printf("log: %s\n", got_object_commit_get_logmsg(commit)); - err = got_object_open(&treeobj, repo, + err = got_object_get_type(&obj_type, repo, got_object_commit_get_tree_id(commit)); - if (err != NULL) + if (err != NULL) { + got_object_commit_close(commit); return err; - if (got_object_get_type(treeobj) == GOT_OBJ_TYPE_TREE) { - print_tree_object(treeobj, "", repo); - test_printf("\n"); } - got_object_close(treeobj); + if (obj_type == GOT_OBJ_TYPE_TREE) + test_printf("\n"); err = print_parent_commits(commit, repo); got_object_commit_close(commit); @@ -202,7 +181,6 @@ repo_read_log(const char *repo_path) struct got_repository *repo; struct got_reference *head_ref; struct got_object_id *id; - struct got_object *obj; char *buf; err = got_repo_open(&repo, repo_path); @@ -219,16 +197,9 @@ repo_read_log(const char *repo_path) return 0; test_printf("HEAD is at %s\n", buf); free(buf); - err = got_object_open(&obj, repo, id); - if (err != NULL || obj == NULL) - return 0; - if (got_object_get_type(obj) == GOT_OBJ_TYPE_COMMIT) { - err = print_commit_object(obj, repo); - if (err) - return 0; - } else + err = print_commit_object(id, repo); + if (err) return 0; - got_object_close(obj); free(id); got_ref_close(head_ref); got_repo_close(repo); @@ -241,21 +212,18 @@ repo_read_tree(const char *repo_path) const char *tree_sha1 = "6cc96e0e093fb30630ba7f199d0a008b24c6a690"; const struct got_error *err; struct got_repository *repo; - struct got_object *obj; + struct got_object_id *id; err = got_repo_open(&repo, repo_path); if (err != NULL || repo == NULL) return 0; - err = got_object_open_by_id_str(&obj, repo, tree_sha1); - if (err != NULL || obj == NULL) + err = got_object_resolve_id_str(&id, repo, tree_sha1); + if (err != NULL) return 0; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_TREE) - return 0; - print_tree_object(obj, "", repo); + print_tree_object(id, "", repo); test_printf("\n"); - got_object_close(obj); got_repo_close(repo); return (err == NULL); } @@ -266,7 +234,7 @@ repo_read_blob(const char *repo_path) const char *blob_sha1 = "141f5fdc96126c1f4195558560a3c915e3d9b4c3"; const struct got_error *err; struct got_repository *repo; - struct got_object *obj; + struct got_object_id *id; struct got_blob_object *blob; int i; size_t len; @@ -274,13 +242,10 @@ repo_read_blob(const char *repo_path) err = got_repo_open(&repo, repo_path); if (err != NULL || repo == NULL) return 0; - err = got_object_open_by_id_str(&obj, repo, blob_sha1); - if (err != NULL || obj == NULL) + err = got_object_resolve_id_str(&id, repo, blob_sha1); + if (err != NULL) return 0; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) - return 0; - - err = got_object_blob_open(&blob, repo, obj, 64); + err = got_object_open_as_blob(&blob, repo, id, 64); if (err != NULL) return 0; @@ -296,7 +261,6 @@ repo_read_blob(const char *repo_path) test_printf("\n"); got_object_blob_close(blob); - got_object_close(obj); got_repo_close(repo); return (err == NULL); } @@ -308,8 +272,7 @@ repo_diff_blob(const char *repo_path) const char *blob2_sha1 = "de7eb21b21c7823a753261aadf7cba35c9580fbf"; const struct got_error *err; struct got_repository *repo; - struct got_object *obj1; - struct got_object *obj2; + struct got_object_id *id1, *id2; struct got_blob_object *blob1; struct got_blob_object *blob2; FILE *outfile; @@ -338,22 +301,19 @@ repo_diff_blob(const char *repo_path) if (err != NULL || repo == NULL) return 0; - err = got_object_open_by_id_str(&obj1, repo, blob1_sha1); - if (err != NULL || obj1 == NULL) - return 0; - if (got_object_get_type(obj1) != GOT_OBJ_TYPE_BLOB) - return 0; - err = got_object_open_by_id_str(&obj2, repo, blob2_sha1); - if (err != NULL || obj2 == NULL) + err = got_object_resolve_id_str(&id1, repo, blob1_sha1); + if (err != NULL) return 0; - if (got_object_get_type(obj2) != GOT_OBJ_TYPE_BLOB) + + err = got_object_resolve_id_str(&id2, repo, blob2_sha1); + if (err != NULL) return 0; - err = got_object_blob_open(&blob1, repo, obj1, 512); + err = got_object_open_as_blob(&blob1, repo, id1, 512); if (err != NULL) return 0; - err = got_object_blob_open(&blob2, repo, obj2, 512); + err = got_object_open_as_blob(&blob2, repo, id2, 512); if (err != NULL) return 0; @@ -385,8 +345,6 @@ repo_diff_blob(const char *repo_path) got_object_blob_close(blob1); got_object_blob_close(blob2); - got_object_close(obj1); - got_object_close(obj2); got_repo_close(repo); return (err == NULL); } @@ -398,8 +356,8 @@ repo_diff_tree(const char *repo_path) const char *tree2_sha1 = "4aa8f2933839ff8a8fb3f905a4c232d22c6ff5f3"; const struct got_error *err; struct got_repository *repo; - struct got_object *obj1; - struct got_object *obj2; + struct got_object_id *id1; + struct got_object_id *id2; struct got_tree_object *tree1; struct got_tree_object *tree2; FILE *outfile; @@ -408,22 +366,18 @@ repo_diff_tree(const char *repo_path) if (err != NULL || repo == NULL) return 0; - err = got_object_open_by_id_str(&obj1, repo, tree1_sha1); - if (err != NULL || obj1 == NULL) + err = got_object_resolve_id_str(&id1, repo, tree1_sha1); + if (err != NULL) return 0; - if (got_object_get_type(obj1) != GOT_OBJ_TYPE_TREE) + err = got_object_resolve_id_str(&id2, repo, tree2_sha1); + if (err != NULL) return 0; - err = got_object_open_by_id_str(&obj2, repo, tree2_sha1); - if (err != NULL || obj2 == NULL) - return 0; - if (got_object_get_type(obj2) != GOT_OBJ_TYPE_TREE) - return 0; - err = got_object_tree_open(&tree1, repo, obj1); + err = got_object_open_as_tree(&tree1, repo, id1); if (err != NULL) return 0; - err = got_object_tree_open(&tree2, repo, obj2); + err = got_object_open_as_tree(&tree2, repo, id2); if (err != NULL) return 0; @@ -439,8 +393,6 @@ repo_diff_tree(const char *repo_path) got_object_tree_close(tree1); got_object_tree_close(tree2); - got_object_close(obj1); - got_object_close(obj2); got_repo_close(repo); return (err == NULL); } blob - e2ca7c7dacf4e7ba9918bc542d28f81a27957444 blob + 6a04b868b4675383fd4f507ceb3a508861fd43e7 --- tog/tog.c +++ tog/tog.c @@ -261,7 +261,7 @@ struct tog_view { }; static const struct got_error *open_diff_view(struct tog_view *, - struct got_object *, struct got_object *, struct got_repository *); + struct got_object_id *, struct got_object_id *, struct got_repository *); static const struct got_error *show_diff_view(struct tog_view *); static const struct got_error *input_diff_view(struct tog_view **, struct tog_view **, struct tog_view **, struct tog_view *, int); @@ -1225,35 +1225,18 @@ open_diff_view_for_commit(struct tog_view **new_view, struct got_repository *repo) { const struct got_error *err; - struct got_object *obj1 = NULL, *obj2 = NULL; struct got_object_qid *parent_id; struct tog_view *diff_view; - - err = got_object_open(&obj2, repo, commit_id); - if (err) - return err; parent_id = SIMPLEQ_FIRST(got_object_commit_get_parent_ids(commit)); - if (parent_id) { - err = got_object_open(&obj1, repo, parent_id->id); - if (err) - goto done; - } diff_view = view_open(0, 0, 0, begin_x, TOG_VIEW_DIFF); - if (diff_view == NULL) { - err = got_error_from_errno(); - goto done; - } + if (diff_view == NULL) + return got_error_from_errno(); - err = open_diff_view(diff_view, obj1, obj2, repo); + err = open_diff_view(diff_view, parent_id->id, commit_id, repo); if (err == NULL) *new_view = diff_view; -done: - if (obj1) - got_object_close(obj1); - if (obj2) - got_object_close(obj2); return err; } @@ -1689,20 +1672,11 @@ cmd_log(int argc, char *argv[]) if (error != NULL) goto done; - if (start_commit == NULL) { + if (start_commit == NULL) error = get_head_commit_id(&start_id, repo); - if (error != NULL) - goto done; - } else { - struct got_object *obj; - error = got_object_open_by_id_str(&obj, repo, start_commit); - if (error == NULL) { - start_id = got_object_id_dup(got_object_get_id(obj)); - if (start_id == NULL) - error = got_error_from_errno(); - goto done; - } - } + else + error = got_object_resolve_id_str(&start_id, repo, + start_commit); if (error != NULL) goto done; @@ -1826,21 +1800,25 @@ get_datestr(time_t *time, char *datebuf) } static const struct got_error * -write_commit_info(struct got_object *obj, struct got_repository *repo, +write_commit_info(struct got_object_id *commit_id, struct got_repository *repo, FILE *outfile) { const struct got_error *err = NULL; - char *id_str; char datebuf[26]; - struct got_commit_object *commit = NULL; + struct got_commit_object *commit; + char *id_str = NULL; time_t committer_time; const char *author, *committer; - err = got_object_id_str(&id_str, got_object_get_id(obj)); + err = got_object_open_as_commit(&commit, repo, commit_id); if (err) return err; - err = got_object_commit_open(&commit, repo, obj); + err = got_object_id_str(&id_str, commit_id); + if (err) { + err = got_error_from_errno(); + goto done; + } if (fprintf(outfile, "commit: %s\n", id_str) < 0) { err = got_error_from_errno(); @@ -1871,8 +1849,7 @@ write_commit_info(struct got_object *obj, struct got_r } done: free(id_str); - if (commit) - got_object_commit_close(commit); + got_object_commit_close(commit); return err; } @@ -1880,19 +1857,9 @@ static const struct got_error * create_diff(struct tog_diff_view_state *s) { const struct got_error *err = NULL; - struct got_object *obj1 = NULL, *obj2 = NULL; FILE *f = NULL; + int obj_type; - if (s->id1) { - err = got_object_open(&obj1, s->repo, s->id1); - if (err) - return err; - } - - err = got_object_open(&obj2, s->repo, s->id2); - if (err) - goto done; - f = got_opentemp(); if (f == NULL) { err = got_error_from_errno(); @@ -1902,13 +1869,20 @@ create_diff(struct tog_diff_view_state *s) fclose(s->f); s->f = f; - switch (got_object_get_type(obj1 ? obj1 : obj2)) { + if (s->id1) + err = got_object_get_type(&obj_type, s->repo, s->id1); + else + err = got_object_get_type(&obj_type, s->repo, s->id2); + if (err) + goto done; + + switch (obj_type) { case GOT_OBJ_TYPE_BLOB: - err = got_diff_objects_as_blobs(obj1, obj2, NULL, NULL, + err = got_diff_objects_as_blobs(s->id1, s->id2, NULL, NULL, s->diff_context, s->repo, f); break; case GOT_OBJ_TYPE_TREE: - err = got_diff_objects_as_trees(obj1, obj2, "", "", + err = got_diff_objects_as_trees(s->id1, s->id2, "", "", s->diff_context, s->repo, f); break; case GOT_OBJ_TYPE_COMMIT: { @@ -1916,22 +1890,21 @@ create_diff(struct tog_diff_view_state *s) struct got_object_qid *pid; struct got_commit_object *commit2; - err = got_object_commit_open(&commit2, s->repo, obj2); + err = got_object_open_as_commit(&commit2, s->repo, s->id2); if (err) break; /* Show commit info if we're diffing to a parent commit. */ parent_ids = got_object_commit_get_parent_ids(commit2); SIMPLEQ_FOREACH(pid, parent_ids, entry) { - struct got_object_id *id1 = got_object_get_id(obj1); - if (got_object_id_cmp(id1, pid->id) == 0) { - write_commit_info(obj2, s->repo, f); + if (got_object_id_cmp(s->id1, pid->id) == 0) { + write_commit_info(s->id2, s->repo, f); break; } } got_object_commit_close(commit2); - err = got_diff_objects_as_commits(obj1, obj2, s->diff_context, - s->repo, f); + err = got_diff_objects_as_commits(s->id1, s->id2, + s->diff_context, s->repo, f); break; } default: @@ -1939,34 +1912,38 @@ create_diff(struct tog_diff_view_state *s) break; } done: - if (obj1) - got_object_close(obj1); - got_object_close(obj2); if (f) fflush(f); return err; } static const struct got_error * -open_diff_view(struct tog_view *view, struct got_object *obj1, - struct got_object *obj2, struct got_repository *repo) +open_diff_view(struct tog_view *view, struct got_object_id *id1, + struct got_object_id *id2, struct got_repository *repo) { const struct got_error *err; - if (obj1 != NULL && obj2 != NULL && - got_object_get_type(obj1) != got_object_get_type(obj2)) + if (id1 != NULL && id2 != NULL) { + int type1, type2; + err = got_object_get_type(&type1, repo, id1); + if (err) + return err; + err = got_object_get_type(&type2, repo, id2); + if (err) + return err; + + if (type1 != type2) return got_error(GOT_ERR_OBJ_TYPE); + } - if (obj1) { - struct got_object_id *id1; - id1 = got_object_id_dup(got_object_get_id(obj1)); - if (id1 == NULL) + if (id1) { + view->state.diff.id1 = got_object_id_dup(id1); + if (view->state.diff.id1 == NULL) return got_error_from_errno(); - view->state.diff.id1 = id1; } else view->state.diff.id1 = NULL; - view->state.diff.id2 = got_object_id_dup(got_object_get_id(obj2)); + view->state.diff.id2 = got_object_id_dup(id2); if (view->state.diff.id2 == NULL) { free(view->state.diff.id1); view->state.diff.id1 = NULL; @@ -2099,9 +2076,9 @@ cmd_diff(int argc, char *argv[]) { const struct got_error *error = NULL; struct got_repository *repo = NULL; - struct got_object *obj1 = NULL, *obj2 = NULL; + struct got_object_id *id1 = NULL, *id2 = NULL; char *repo_path = NULL; - char *obj_id_str1 = NULL, *obj_id_str2 = NULL; + char *id_str1 = NULL, *id_str2 = NULL; int ch; struct tog_view *view; @@ -2128,14 +2105,14 @@ cmd_diff(int argc, char *argv[]) repo_path = getcwd(NULL, 0); if (repo_path == NULL) return got_error_from_errno(); - obj_id_str1 = argv[0]; - obj_id_str2 = argv[1]; + id_str1 = argv[0]; + id_str2 = argv[1]; } else if (argc == 3) { repo_path = realpath(argv[0], NULL); if (repo_path == NULL) return got_error_from_errno(); - obj_id_str1 = argv[1]; - obj_id_str2 = argv[2]; + id_str1 = argv[1]; + id_str2 = argv[2]; } else usage_diff(); @@ -2144,11 +2121,11 @@ cmd_diff(int argc, char *argv[]) if (error) goto done; - error = got_object_open_by_id_str(&obj1, repo, obj_id_str1); + error = got_object_resolve_id_str(&id1, repo, id_str1); if (error) goto done; - error = got_object_open_by_id_str(&obj2, repo, obj_id_str2); + error = got_object_resolve_id_str(&id2, repo, id_str2); if (error) goto done; @@ -2157,16 +2134,12 @@ cmd_diff(int argc, char *argv[]) error = got_error_from_errno(); goto done; } - error = open_diff_view(view, obj1, obj2, repo); + error = open_diff_view(view, id1, id2, repo); if (error) goto done; error = view_loop(view); done: got_repo_close(repo); - if (obj1) - got_object_close(obj1); - if (obj2) - got_object_close(obj2); return error; } @@ -2374,8 +2347,8 @@ blame_thread(void *arg) } static struct got_object_id * -get_selected_commit_id(struct tog_blame_line *lines, - int first_displayed_line, int selected_line) +get_selected_commit_id(struct tog_blame_line *lines, int first_displayed_line, + int selected_line) { struct tog_blame_line *line; @@ -2384,44 +2357,6 @@ get_selected_commit_id(struct tog_blame_line *lines, return NULL; return line->id; -} - -static const struct got_error * -open_selected_commit(struct got_object **pobj, struct got_object **obj, - struct tog_blame_line *lines, int first_displayed_line, - int selected_line, struct got_repository *repo) -{ - const struct got_error *err = NULL; - struct got_commit_object *commit = NULL; - struct got_object_id *selected_id; - struct got_object_qid *pid; - - *pobj = NULL; - *obj = NULL; - - selected_id = get_selected_commit_id(lines, - first_displayed_line, selected_line); - if (selected_id == NULL) - return NULL; - - err = got_object_open(obj, repo, selected_id); - if (err) - goto done; - - err = got_object_commit_open(&commit, repo, *obj); - if (err) - goto done; - - pid = SIMPLEQ_FIRST(got_object_commit_get_parent_ids(commit)); - if (pid) { - err = got_object_open(pobj, repo, pid->id); - if (err) - goto done; - } -done: - if (commit) - got_object_commit_close(commit); - return err; } static const struct got_error * @@ -2475,22 +2410,24 @@ run_blame(struct tog_blame *blame, struct tog_view *vi struct got_blob_object *blob = NULL; struct got_repository *thread_repo = NULL; struct got_object_id *obj_id = NULL; - struct got_object *obj = NULL; + int obj_type; err = got_object_id_by_path(&obj_id, repo, commit_id, path); if (err) - goto done; + return err; + if (obj_id == NULL) + return got_error(GOT_ERR_NO_OBJ); - err = got_object_open(&obj, repo, obj_id); + err = got_object_get_type(&obj_type, repo, obj_id); if (err) goto done; - if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) { + if (obj_type != GOT_OBJ_TYPE_BLOB) { err = got_error(GOT_ERR_OBJ_TYPE); goto done; } - err = got_object_blob_open(&blob, repo, obj, 8192); + err = got_object_open_as_blob(&blob, repo, obj_id, 8192); if (err) goto done; blame->f = got_opentemp(); @@ -2533,8 +2470,6 @@ done: if (blob) got_object_blob_close(blob); free(obj_id); - if (obj) - got_object_close(obj); if (err) stop_blame(blame); return err; @@ -2624,7 +2559,6 @@ input_blame_view(struct tog_view **new_view, struct to struct tog_view **focus_view, struct tog_view *view, int ch) { const struct got_error *err = NULL, *thread_err = NULL; - struct got_object *obj = NULL, *pobj = NULL; struct tog_view *diff_view; struct tog_blame_view_state *s = &view->state.blame; int begin_x = 0; @@ -2664,36 +2598,60 @@ input_blame_view(struct tog_view **new_view, struct to break; case 'b': case 'p': { - struct got_object_id *id; + struct got_object_id *id = NULL; id = get_selected_commit_id(s->blame.lines, s->first_displayed_line, s->selected_line); - if (id == NULL || got_object_id_cmp(id, - s->blamed_commit->id) == 0) + if (id == NULL) break; - err = open_selected_commit(&pobj, &obj, - s->blame.lines, s->first_displayed_line, - s->selected_line, s->repo); + if (ch == 'p') { + struct got_commit_object *commit; + struct got_object_qid *pid; + struct got_object_id *blob_id = NULL; + int obj_type; + err = got_object_open_as_commit(&commit, + s->repo, id); + if (err) + break; + pid = SIMPLEQ_FIRST( + got_object_commit_get_parent_ids(commit)); + if (pid == NULL) { + got_object_commit_close(commit); + break; + } + /* Check if path history ends here. */ + err = got_object_id_by_path(&blob_id, s->repo, + pid->id, s->path); + if (err) { + if (err->code == GOT_ERR_NO_TREE_ENTRY) + err = NULL; + got_object_commit_close(commit); + break; + } + err = got_object_get_type(&obj_type, s->repo, + blob_id); + free(blob_id); + /* Can't blame non-blob type objects. */ + if (obj_type != GOT_OBJ_TYPE_BLOB) { + got_object_commit_close(commit); + break; + } + err = got_object_qid_alloc(&s->blamed_commit, + pid->id); + got_object_commit_close(commit); + } else { + if (got_object_id_cmp(id, + s->blamed_commit->id) == 0) + break; + err = got_object_qid_alloc(&s->blamed_commit, + id); + } if (err) break; - if (pobj == NULL && obj == NULL) - break; - if (ch == 'p' && pobj == NULL) - break; s->done = 1; thread_err = stop_blame(&s->blame); s->done = 0; if (thread_err) break; - id = got_object_get_id(ch == 'b' ? obj : pobj); - got_object_close(obj); - obj = NULL; - if (pobj) { - got_object_close(pobj); - pobj = NULL; - } - err = got_object_qid_alloc(&s->blamed_commit, id); - if (err) - goto done; SIMPLEQ_INSERT_HEAD(&s->blamed_commits, s->blamed_commit, entry); err = run_blame(&s->blame, view, &s->blame_complete, @@ -2727,23 +2685,31 @@ input_blame_view(struct tog_view **new_view, struct to break; } case KEY_ENTER: - case '\r': - err = open_selected_commit(&pobj, &obj, - s->blame.lines, s->first_displayed_line, - s->selected_line, s->repo); + case '\r': { + struct got_object_id *id = NULL; + struct got_object_qid *pid; + struct got_commit_object *commit = NULL; + id = get_selected_commit_id(s->blame.lines, + s->first_displayed_line, s->selected_line); + if (id == NULL || got_object_id_cmp(id, + s->blamed_commit->id) == 0) + break; + err = got_object_open_as_commit(&commit, s->repo, id); if (err) break; - if (pobj == NULL && obj == NULL) - break; - + pid = SIMPLEQ_FIRST( + got_object_commit_get_parent_ids(commit)); if (view_is_parent_view(view)) begin_x = view_split_begin_x(view->begin_x); diff_view = view_open(0, 0, 0, begin_x, TOG_VIEW_DIFF); if (diff_view == NULL) { + got_object_commit_close(commit); err = got_error_from_errno(); break; } - err = open_diff_view(diff_view, pobj, obj, s->repo); + err = open_diff_view(diff_view, pid ? pid->id : NULL, + id, s->repo); + got_object_commit_close(commit); if (err) { view_close(diff_view); break; @@ -2751,7 +2717,7 @@ input_blame_view(struct tog_view **new_view, struct to if (view_is_parent_view(view)) { err = view_close_child(view); if (err) - return err; + break; err = view_set_child(view, diff_view); if (err) { view_close(diff_view); @@ -2761,15 +2727,10 @@ input_blame_view(struct tog_view **new_view, struct to view->child_focussed = 1; } else *new_view = diff_view; - if (pobj) { - got_object_close(pobj); - pobj = NULL; - } - got_object_close(obj); - obj = NULL; if (err) break; break; + } case KEY_NPAGE: case ' ': if (s->last_displayed_line >= s->blame.nlines && @@ -2796,9 +2757,6 @@ input_blame_view(struct tog_view **new_view, struct to default: break; } -done: - if (pobj) - got_object_close(pobj); return thread_err ? thread_err : err; } @@ -2873,14 +2831,8 @@ cmd_blame(int argc, char *argv[]) error = got_ref_resolve(&commit_id, repo, head_ref); got_ref_close(head_ref); } else { - struct got_object *obj; - error = got_object_open_by_id_str(&obj, repo, commit_id_str); - if (error != NULL) - goto done; - commit_id = got_object_id_dup(got_object_get_id(obj)); - if (commit_id == NULL) - error = got_error_from_errno(); - got_object_close(obj); + error = got_object_resolve_id_str(&commit_id, repo, + commit_id_str); } if (error != NULL) goto done; @@ -3462,19 +3414,11 @@ cmd_tree(int argc, char *argv[]) if (error != NULL) return error; - if (commit_id_arg == NULL) { + if (commit_id_arg == NULL) error = get_head_commit_id(&commit_id, repo); - if (error != NULL) - goto done; - } else { - struct got_object *obj; - error = got_object_open_by_id_str(&obj, repo, commit_id_arg); - if (error == NULL) { - commit_id = got_object_id_dup(got_object_get_id(obj)); - if (commit_id == NULL) - error = got_error_from_errno(); - } - } + else + error = got_object_resolve_id_str(&commit_id, repo, + commit_id_arg); if (error != NULL) goto done;