Download raw body.
got_object_id_by_path() vs. commit object cache
Stop relying on the commit object cache for reasoable performance of got_object_id_by_path(). This function is called over and over on the same commit by commands like 'got tree -R'. Instead of internally opening and closing the same commit object over and over again, require callers to pass an open commit object in. Avoids an inherent dependency on the commit object cache for reasonable performance of this function. My end goal is to eventually get rid of the commit object cache altogether because this cache seems to be slowing down operations like 'gotadmin pack'. The cache is only useful when commits are accessed repeatedly and very often, which is rarely the case. Usually, operations open one commit as an anchor to start from, or they open commits in sequence and do not process a given commit more than once. In such cases the object cache management overhead provides no benefit and just slows things down. ok? diff 720c84593b989629674c0c2d566b6fcb246578fd 521d106ce83778863df98a05bad26f95fef30494 blob - f3608d970c5ae77fee89a4e9ca8fdb89b015c5f8 blob + 7ac9d84ea1bc903f4fd7ab569799630bbaa48aaa --- got/got.c +++ got/got.c @@ -3609,7 +3609,7 @@ print_patch(struct got_commit_object *commit, struct g if (path && path[0] != '\0') { int obj_type; - err = got_object_id_by_path(&obj_id2, repo, id, path); + err = got_object_id_by_path(&obj_id2, repo, commit, path); if (err) goto done; err = got_object_id_str(&id_str2, obj_id2); @@ -3619,7 +3619,7 @@ print_patch(struct got_commit_object *commit, struct g } if (pcommit) { err = got_object_id_by_path(&obj_id1, repo, - qid->id, path); + pcommit, path); if (err) { if (err->code != GOT_ERR_NO_TREE_ENTRY) { free(obj_id2); @@ -4984,6 +4984,7 @@ cmd_blame(int argc, char *argv[]) char *link_target = NULL; struct got_object_id *obj_id = NULL; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; struct got_blob_object *blob = NULL; char *commit_id_str = NULL; struct blame_cb_args bca; @@ -5111,12 +5112,16 @@ cmd_blame(int argc, char *argv[]) worktree = NULL; } + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + error = got_object_resolve_symlinks(&link_target, in_repo_path, - commit_id, repo); + commit, repo); if (error) goto done; - error = got_object_id_by_path(&obj_id, repo, commit_id, + error = got_object_id_by_path(&obj_id, repo, commit, link_target ? link_target : in_repo_path); if (error) goto done; @@ -5171,6 +5176,8 @@ done: free(cwd); free(commit_id); free(obj_id); + if (commit) + got_object_commit_close(commit); if (blob) got_object_blob_close(blob); if (worktree) @@ -5246,7 +5253,7 @@ print_entry(struct got_tree_entry *te, const char *id, } static const struct got_error * -print_tree(const char *path, struct got_object_id *commit_id, +print_tree(const char *path, struct got_commit_object *commit, int show_ids, int recurse, const char *root_path, struct got_repository *repo) { @@ -5255,7 +5262,7 @@ print_tree(const char *path, struct got_object_id *com struct got_tree_object *tree = NULL; int nentries, i; - err = got_object_id_by_path(&tree_id, repo, commit_id, path); + err = got_object_id_by_path(&tree_id, repo, commit, path); if (err) goto done; @@ -5297,7 +5304,7 @@ print_tree(const char *path, struct got_object_id *com err = got_error_from_errno("asprintf"); goto done; } - err = print_tree(child_path, commit_id, show_ids, 1, + err = print_tree(child_path, commit, show_ids, 1, root_path, repo); free(child_path); if (err) @@ -5320,6 +5327,7 @@ cmd_tree(int argc, char *argv[]) const char *path, *refname = NULL; char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; char *commit_id_str = NULL; int show_ids = 0, recurse = 0; int ch; @@ -5459,13 +5467,19 @@ cmd_tree(int argc, char *argv[]) worktree = NULL; } - error = print_tree(in_repo_path, commit_id, show_ids, recurse, + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + + error = print_tree(in_repo_path, commit, show_ids, recurse, in_repo_path, repo); done: free(in_repo_path); free(repo_path); free(cwd); free(commit_id); + if (commit) + got_object_commit_close(commit); if (worktree) got_worktree_close(worktree); if (repo) { @@ -11830,6 +11844,7 @@ cmd_cat(int argc, char *argv[]) char *cwd = NULL, *repo_path = NULL, *label = NULL; const char *commit_id_str = NULL; struct got_object_id *id = NULL, *commit_id = NULL; + struct got_commit_object *commit = NULL; int ch, obj_type, i, force_path = 0; struct got_reflist_head refs; @@ -11914,9 +11929,13 @@ cmd_cat(int argc, char *argv[]) if (error) goto done; + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + for (i = 0; i < argc; i++) { if (force_path) { - error = got_object_id_by_path(&id, repo, commit_id, + error = got_object_id_by_path(&id, repo, commit, argv[i]); if (error) break; @@ -11929,7 +11948,7 @@ cmd_cat(int argc, char *argv[]) error->code != GOT_ERR_NOT_REF) break; error = got_object_id_by_path(&id, repo, - commit_id, argv[i]); + commit, argv[i]); if (error) break; } @@ -11967,6 +11986,8 @@ done: free(label); free(id); free(commit_id); + if (commit) + got_object_commit_close(commit); if (worktree) got_worktree_close(worktree); if (repo) { blob - 592e77655be88e831265856057c0f2f4d253128e blob + 9d6f362ad6242f2fdff94792bc113ede1710807d --- include/got_object.h +++ include/got_object.h @@ -106,7 +106,7 @@ const struct got_error *got_object_tree_find_path(stru * The caller should dispose of it with free(3). */ const struct got_error *got_object_id_by_path(struct got_object_id **, - struct got_repository *, struct got_object_id *, const char *); + struct got_repository *, struct got_commit_object *, const char *); /* * Obtain the type of an object. @@ -241,7 +241,7 @@ int got_object_tree_entry_is_symlink(struct got_tree_e * target path. The caller must dispose of it with free(3). */ const struct got_error *got_object_resolve_symlinks(char **, const char *, - struct got_object_id *, struct got_repository *); + struct got_commit_object *, struct got_repository *); /* * Compare two trees and indicate whether the entry at the specified path blob - d2db8c1e2cd6a46130821551a293b51fa2c841b9 blob + 4fb57b680144beb72b8bb8898b73e6d032ad15d8 --- lib/blame.c +++ lib/blame.c @@ -200,7 +200,7 @@ blame_commit(struct got_blame *blame, struct got_objec void *arg) { const struct got_error *err = NULL; - struct got_commit_object *commit = NULL; + struct got_commit_object *commit = NULL, *pcommit = NULL; struct got_object_qid *pid = NULL; struct got_object_id *pblob_id = NULL; struct got_blob_object *pblob = NULL; @@ -216,7 +216,11 @@ blame_commit(struct got_blame *blame, struct got_objec return NULL; } - err = got_object_id_by_path(&pblob_id, repo, pid->id, path); + err = got_object_open_as_commit(&pcommit, repo, pid->id); + if (err) + goto done; + + err = got_object_id_by_path(&pblob_id, repo, pcommit, path); if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) err = NULL; @@ -267,6 +271,8 @@ done: diff_result_free(diff_result); if (commit) got_object_commit_close(commit); + if (pcommit) + got_object_commit_close(pcommit); free(pblob_id); if (pblob) got_object_blob_close(pblob); @@ -498,6 +504,7 @@ blame_open(struct got_blame **blamep, const char *path void *arg, got_cancel_cb cancel_cb, void *cancel_arg) { const struct got_error *err = NULL; + struct got_commit_object *start_commit = NULL; struct got_object_id *obj_id = NULL; struct got_blob_object *blob = NULL; struct got_blame *blame = NULL; @@ -507,10 +514,14 @@ blame_open(struct got_blame **blamep, const char *path *blamep = NULL; - err = got_object_id_by_path(&obj_id, repo, start_commit_id, path); + err = got_object_open_as_commit(&start_commit, repo, start_commit_id); if (err) goto done; + err = got_object_id_by_path(&obj_id, repo, start_commit, path); + if (err) + goto done; + err = got_object_open_as_blob(&blob, repo, obj_id, 8192); if (err) goto done; @@ -621,6 +632,8 @@ done: free(obj_id); if (blob) got_object_blob_close(blob); + if (start_commit) + got_object_commit_close(start_commit); if (err) { if (blame) blame_close(blame); blob - 55b4da29492815a14efed2a3680b55d68dddbfd0 blob + 644fd4c564841be0c8142f649c9e68f26133deb7 --- lib/commit_graph.c +++ lib/commit_graph.c @@ -112,7 +112,7 @@ detect_changed_path(int *changed, struct got_commit_ob pid = STAILQ_FIRST(&commit->parent_ids); if (pid == NULL) { struct got_object_id *obj_id; - err = got_object_id_by_path(&obj_id, repo, commit_id, path); + err = got_object_id_by_path(&obj_id, repo, commit, path); if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) err = NULL; @@ -293,20 +293,30 @@ advance_branch(struct got_commit_graph *graph, struct struct got_object_id *merged_id, *prev_id = NULL; int branches_differ = 0; - err = got_object_id_by_path(&merged_id, repo, commit_id, + err = got_object_id_by_path(&merged_id, repo, commit, graph->path); if (err) return err; STAILQ_FOREACH(qid, &commit->parent_ids, entry) { - struct got_object_id *id; + struct got_object_id *id = NULL; + struct got_commit_object *pcommit = NULL; if (got_object_idset_contains(graph->open_branches, qid->id)) continue; - err = got_object_id_by_path(&id, repo, qid->id, + err = got_object_open_as_commit(&pcommit, repo, + qid->id); + if (err) { + free(merged_id); + free(prev_id); + return err; + } + err = got_object_id_by_path(&id, repo, pcommit, graph->path); + got_object_commit_close(pcommit); + pcommit = NULL; if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) { branches_differ = 1; blob - 8218b2c4c146e832c63f84d4a9f6a43f8b3283f8 blob + f6a83e12b20b326cac3cf14c4fe93d71d56a2775 --- lib/object.c +++ lib/object.c @@ -1998,18 +1998,13 @@ done: } const struct got_error * got_object_id_by_path(struct got_object_id **id, struct got_repository *repo, - struct got_object_id *commit_id, const char *path) + struct got_commit_object *commit, const char *path) { const struct got_error *err = NULL; - struct got_commit_object *commit = NULL; struct got_tree_object *tree = NULL; *id = NULL; - err = got_object_open_as_commit(&commit, repo, commit_id); - if (err) - goto done; - /* Handle opening of root of commit's tree. */ if (got_path_is_root_dir(path)) { *id = got_object_id_dup(commit->tree_id); @@ -2022,8 +2017,6 @@ got_object_id_by_path(struct got_object_id **id, struc err = got_object_tree_find_path(id, NULL, repo, tree, path); } done: - if (commit) - got_object_commit_close(commit); if (tree) got_object_tree_close(tree); return err; @@ -2187,7 +2180,7 @@ got_object_tree_entry_is_symlink(struct got_tree_entry static const struct got_error * resolve_symlink(char **link_target, const char *path, - struct got_object_id *commit_id, struct got_repository *repo) + struct got_commit_object *commit, struct got_repository *repo) { const struct got_error *err = NULL; char buf[PATH_MAX]; @@ -2209,7 +2202,7 @@ resolve_symlink(char **link_target, const char *path, if (err) return err; - err = got_object_id_by_path(&tree_obj_id, repo, commit_id, + err = got_object_id_by_path(&tree_obj_id, repo, commit, parent_path); if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) { @@ -2265,7 +2258,7 @@ done: const struct got_error * got_object_resolve_symlinks(char **link_target, const char *path, - struct got_object_id *commit_id, struct got_repository *repo) + struct got_commit_object *commit, struct got_repository *repo) { const struct got_error *err = NULL; char *next_target = NULL; @@ -2275,7 +2268,7 @@ got_object_resolve_symlinks(char **link_target, const do { err = resolve_symlink(&next_target, - *link_target ? *link_target : path, commit_id, repo); + *link_target ? *link_target : path, commit, repo); if (err) break; if (next_target) { blob - 16eebc519859d846026d968e3e953c502035de48 blob + bfebb46526cc0f3f0deda90d0868edad7c6946c9 --- lib/worktree.c +++ lib/worktree.c @@ -2459,7 +2459,8 @@ done: static const struct got_error * find_tree_entry_for_checkout(int *entry_type, char **tree_relpath, struct got_object_id **tree_id, const char *wt_relpath, - struct got_worktree *worktree, struct got_repository *repo) + struct got_commit_object *base_commit, struct got_worktree *worktree, + struct got_repository *repo) { const struct got_error *err = NULL; struct got_object_id *id = NULL; @@ -2478,8 +2479,8 @@ find_tree_entry_for_checkout(int *entry_type, char **t err = got_error_from_errno("strdup"); goto done; } - err = got_object_id_by_path(tree_id, repo, - worktree->base_commit_id, worktree->path_prefix); + err = got_object_id_by_path(tree_id, repo, base_commit, + worktree->path_prefix); if (err) goto done; return NULL; @@ -2493,8 +2494,7 @@ find_tree_entry_for_checkout(int *entry_type, char **t goto done; } - err = got_object_id_by_path(&id, repo, worktree->base_commit_id, - in_repo_path); + err = got_object_id_by_path(&id, repo, base_commit, in_repo_path); if (err) goto done; @@ -2532,7 +2532,7 @@ find_tree_entry_for_checkout(int *entry_type, char **t } } err = got_object_id_by_path(tree_id, repo, - worktree->base_commit_id, in_repo_path); + base_commit, in_repo_path); } else { /* Check out all files within a subdirectory. */ *tree_id = got_object_id_dup(id); @@ -2644,6 +2644,11 @@ got_worktree_checkout_files(struct got_worktree *workt if (err) return err; + err = got_object_open_as_commit(&commit, repo, + worktree->base_commit_id); + if (err) + goto done; + /* Map all specified paths to in-repository trees. */ TAILQ_FOREACH(pe, paths, entry) { tpd = malloc(sizeof(*tpd)); @@ -2653,7 +2658,8 @@ got_worktree_checkout_files(struct got_worktree *workt } err = find_tree_entry_for_checkout(&tpd->entry_type, - &tpd->relpath, &tpd->tree_id, pe->path, worktree, repo); + &tpd->relpath, &tpd->tree_id, pe->path, commit, + worktree, repo); if (err) { free(tpd); goto done; @@ -3095,12 +3101,16 @@ merge_files(struct got_worktree *worktree, struct got_ const struct got_error *err = NULL, *sync_err; struct got_object_id *tree_id1 = NULL, *tree_id2 = NULL; struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_commit_object *commit1 = NULL, *commit2 = NULL; struct check_merge_conflicts_arg cmc_arg; struct merge_file_cb_arg arg; char *label_orig = NULL; if (commit_id1) { - err = got_object_id_by_path(&tree_id1, repo, commit_id1, + err = got_object_open_as_commit(&commit1, repo, commit_id1); + if (err) + goto done; + err = got_object_id_by_path(&tree_id1, repo, commit1, worktree->path_prefix); if (err && err->code != GOT_ERR_NO_TREE_ENTRY) goto done; @@ -3125,7 +3135,11 @@ merge_files(struct got_worktree *worktree, struct got_ free(id_str); } - err = got_object_id_by_path(&tree_id2, repo, commit_id2, + err = got_object_open_as_commit(&commit2, repo, commit_id2); + if (err) + goto done; + + err = got_object_id_by_path(&tree_id2, repo, commit2, worktree->path_prefix); if (err) goto done; @@ -3156,6 +3170,10 @@ merge_files(struct got_worktree *worktree, struct got_ if (sync_err && err == NULL) err = sync_err; done: + if (commit1) + got_object_commit_close(commit1); + if (commit2) + got_object_commit_close(commit2); if (tree1) got_object_tree_close(tree1); if (tree2) @@ -4544,6 +4562,7 @@ revert_file(void *arg, unsigned char status, unsigned const struct got_error *err = NULL; char *parent_path = NULL; struct got_fileindex_entry *ie; + struct got_commit_object *base_commit = NULL; struct got_tree_object *tree = NULL; struct got_object_id *tree_id = NULL; const struct got_tree_entry *te = NULL; @@ -4597,8 +4616,12 @@ revert_file(void *arg, unsigned char status, unsigned } } - err = got_object_id_by_path(&tree_id, a->repo, - a->worktree->base_commit_id, tree_path); + err = got_object_open_as_commit(&base_commit, a->repo, + a->worktree->base_commit_id); + if (err) + goto done; + + err = got_object_id_by_path(&tree_id, a->repo, base_commit, tree_path); if (err) { if (!(err->code == GOT_ERR_NO_TREE_ENTRY && (status == GOT_STATUS_ADD || @@ -4756,6 +4779,8 @@ done: if (tree) got_object_tree_close(tree); free(tree_id); + if (base_commit) + got_object_commit_close(base_commit); return err; } @@ -5513,6 +5538,7 @@ check_out_of_date(const char *in_repo_path, unsigned c int ood_errcode) { const struct got_error *err = NULL; + struct got_commit_object *commit = NULL; struct got_object_id *id = NULL; if (status != GOT_STATUS_ADD && staged_status != GOT_STATUS_ADD) { @@ -5523,8 +5549,10 @@ check_out_of_date(const char *in_repo_path, unsigned c * Ensure file content which local changes were based * on matches file content in the branch head. */ - err = got_object_id_by_path(&id, repo, head_commit_id, - in_repo_path); + err = got_object_open_as_commit(&commit, repo, head_commit_id); + if (err) + goto done; + err = got_object_id_by_path(&id, repo, commit, in_repo_path); if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) err = got_error(ood_errcode); @@ -5533,14 +5561,18 @@ check_out_of_date(const char *in_repo_path, unsigned c err = got_error(ood_errcode); } else { /* Require that added files don't exist in the branch head. */ - err = got_object_id_by_path(&id, repo, head_commit_id, - in_repo_path); + err = got_object_open_as_commit(&commit, repo, head_commit_id); + if (err) + goto done; + err = got_object_id_by_path(&id, repo, commit, in_repo_path); if (err && err->code != GOT_ERR_NO_TREE_ENTRY) goto done; err = id ? got_error(ood_errcode) : NULL; } done: free(id); + if (commit) + got_object_commit_close(commit); return err; } @@ -6692,6 +6724,7 @@ got_worktree_rebase_abort(struct got_worktree *worktre const struct got_error *err, *unlockerr, *sync_err; struct got_reference *resolved = NULL; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; char *fileindex_path = NULL; struct revert_file_args rfa; struct got_object_id *tree_id = NULL; @@ -6700,6 +6733,11 @@ got_worktree_rebase_abort(struct got_worktree *worktre if (err) return err; + err = got_object_open_as_commit(&commit, repo, + worktree->base_commit_id); + if (err) + goto done; + err = got_ref_open(&resolved, repo, got_ref_get_symref_target(new_base_branch), 0); if (err) @@ -6722,8 +6760,8 @@ got_worktree_rebase_abort(struct got_worktree *worktre if (err) goto done; - err = got_object_id_by_path(&tree_id, repo, - worktree->base_commit_id, worktree->path_prefix); + err = got_object_id_by_path(&tree_id, repo, commit, + worktree->path_prefix); if (err) goto done; @@ -6758,6 +6796,8 @@ done: got_ref_close(resolved); free(tree_id); free(commit_id); + if (commit) + got_object_commit_close(commit); if (fileindex) got_fileindex_free(fileindex); free(fileindex_path); @@ -7056,6 +7096,7 @@ got_worktree_histedit_abort(struct got_worktree *workt const struct got_error *err, *unlockerr, *sync_err; struct got_reference *resolved = NULL; char *fileindex_path = NULL; + struct got_commit_object *commit = NULL; struct got_object_id *tree_id = NULL; struct revert_file_args rfa; @@ -7063,6 +7104,11 @@ got_worktree_histedit_abort(struct got_worktree *workt if (err) return err; + err = got_object_open_as_commit(&commit, repo, + worktree->base_commit_id); + if (err) + goto done; + err = got_ref_open(&resolved, repo, got_ref_get_symref_target(branch), 0); if (err) @@ -7076,7 +7122,7 @@ got_worktree_histedit_abort(struct got_worktree *workt if (err) goto done; - err = got_object_id_by_path(&tree_id, repo, base_commit_id, + err = got_object_id_by_path(&tree_id, repo, commit, worktree->path_prefix); if (err) goto done; @@ -7269,6 +7315,7 @@ got_worktree_integrate_continue(struct got_worktree *w const struct got_error *err = NULL, *sync_err, *unlockerr; char *fileindex_path = NULL; struct got_object_id *tree_id = NULL, *commit_id = NULL; + struct got_commit_object *commit = NULL; err = get_fileindex_path(&fileindex_path, worktree); if (err) @@ -7278,7 +7325,11 @@ got_worktree_integrate_continue(struct got_worktree *w if (err) goto done; - err = got_object_id_by_path(&tree_id, repo, commit_id, + err = got_object_open_as_commit(&commit, repo, commit_id); + if (err) + goto done; + + err = got_object_id_by_path(&tree_id, repo, commit, worktree->path_prefix); if (err) goto done; @@ -7320,6 +7371,8 @@ done: got_fileindex_free(fileindex); free(fileindex_path); free(tree_id); + if (commit) + got_object_commit_close(commit); unlockerr = lock_worktree(worktree, LOCK_SH); if (unlockerr && err == NULL) @@ -7780,15 +7833,21 @@ got_worktree_merge_abort(struct got_worktree *worktree { const struct got_error *err, *unlockerr, *sync_err; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; char *fileindex_path = NULL; struct revert_file_args rfa; struct got_object_id *tree_id = NULL; - err = got_object_id_by_path(&tree_id, repo, - worktree->base_commit_id, worktree->path_prefix); + err = got_object_open_as_commit(&commit, repo, + worktree->base_commit_id); if (err) goto done; + err = got_object_id_by_path(&tree_id, repo, commit, + worktree->path_prefix); + if (err) + goto done; + err = delete_merge_refs(worktree, repo); if (err) goto done; @@ -7819,6 +7878,8 @@ sync: done: free(tree_id); free(commit_id); + if (commit) + got_object_commit_close(commit); if (fileindex) got_fileindex_free(fileindex); free(fileindex_path); blob - 162cb7c902a68e5ba42a938f863e0f9846e84b1a blob + cf640001b1d644e38bc4909d42362dd3ed7f348e --- tog/tog.c +++ tog/tog.c @@ -1910,7 +1910,7 @@ tree_view_visit_subtree(struct tog_tree_view_state *s, static const struct got_error * tree_view_walk_path(struct tog_tree_view_state *s, - struct got_object_id *commit_id, const char *path) + struct got_commit_object *commit, const char *path) { const struct got_error *err = NULL; struct got_tree_object *tree = NULL; @@ -1959,7 +1959,7 @@ tree_view_walk_path(struct tog_tree_view_state *s, break; } - err = got_object_id_by_path(&tree_id, s->repo, commit_id, + err = got_object_id_by_path(&tree_id, s->repo, commit, subpath); if (err) break; @@ -2008,7 +2008,7 @@ browse_commit_tree(struct tog_view **new_view, int beg if (got_path_is_root_dir(path)) return NULL; - return tree_view_walk_path(s, entry->id, path); + return tree_view_walk_path(s, entry->commit, path); } static const struct got_error * @@ -4329,16 +4329,21 @@ run_blame(struct tog_view *view) struct tog_blame_view_state *s = &view->state.blame; struct tog_blame *blame = &s->blame; const struct got_error *err = NULL; + struct got_commit_object *commit = NULL; struct got_blob_object *blob = NULL; struct got_repository *thread_repo = NULL; struct got_object_id *obj_id = NULL; int obj_type; - err = got_object_id_by_path(&obj_id, s->repo, s->blamed_commit->id, - s->path); + err = got_object_open_as_commit(&commit, s->repo, + s->blamed_commit->id); if (err) return err; + err = got_object_id_by_path(&obj_id, s->repo, commit, s->path); + if (err) + goto done; + err = got_object_get_type(&obj_type, s->repo, obj_id); if (err) goto done; @@ -4405,6 +4410,8 @@ run_blame(struct tog_view *view) s->matched_line = 0; done: + if (commit) + got_object_commit_close(commit); if (blob) got_object_blob_close(blob); free(obj_id); @@ -4646,7 +4653,7 @@ input_blame_view(struct tog_view **new_view, struct to if (id == NULL) break; if (ch == 'p') { - struct got_commit_object *commit; + struct got_commit_object *commit, *pcommit; struct got_object_qid *pid; struct got_object_id *blob_id = NULL; int obj_type; @@ -4661,8 +4668,13 @@ input_blame_view(struct tog_view **new_view, struct to break; } /* Check if path history ends here. */ + err = got_object_open_as_commit(&pcommit, + s->repo, pid->id); + if (err) + break; err = got_object_id_by_path(&blob_id, s->repo, - pid->id, s->path); + pcommit, s->path); + got_object_commit_close(pcommit); if (err) { if (err->code == GOT_ERR_NO_TREE_ENTRY) err = NULL; @@ -4807,6 +4819,7 @@ cmd_blame(int argc, char *argv[]) char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; char *link_target = NULL; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; char *commit_id_str = NULL; int ch; struct tog_view *view; @@ -4892,8 +4905,12 @@ cmd_blame(int argc, char *argv[]) goto done; } + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + error = got_object_resolve_symlinks(&link_target, in_repo_path, - commit_id, repo); + commit, repo); if (error) goto done; @@ -4913,6 +4930,8 @@ done: free(link_target); free(cwd); free(commit_id); + if (commit) + got_object_commit_close(commit); if (worktree) got_worktree_close(worktree); if (repo) { @@ -5659,6 +5678,7 @@ cmd_tree(int argc, char *argv[]) struct got_worktree *worktree = NULL; char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; struct got_object_id *commit_id = NULL; + struct got_commit_object *commit = NULL; const char *commit_id_arg = NULL; char *label = NULL; struct got_reference *ref = NULL; @@ -5745,6 +5765,10 @@ cmd_tree(int argc, char *argv[]) goto done; } + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + view = view_open(0, 0, 0, 0, TOG_VIEW_TREE); if (view == NULL) { error = got_error_from_errno("view_open"); @@ -5754,7 +5778,7 @@ cmd_tree(int argc, char *argv[]) if (error) goto done; if (!got_path_is_root_dir(in_repo_path)) { - error = tree_view_walk_path(&view->state.tree, commit_id, + error = tree_view_walk_path(&view->state.tree, commit, in_repo_path); if (error) goto done; @@ -6559,6 +6583,7 @@ tog_log_with_path(int argc, char *argv[]) struct got_repository *repo = NULL; struct got_worktree *worktree = NULL; struct got_object_id *commit_id = NULL, *id = NULL; + struct got_commit_object *commit = NULL; char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; char *commit_id_str = NULL, **cmd_argv = NULL; @@ -6602,7 +6627,11 @@ tog_log_with_path(int argc, char *argv[]) worktree = NULL; } - error = got_object_id_by_path(&id, repo, commit_id, in_repo_path); + error = got_object_open_as_commit(&commit, repo, commit_id); + if (error) + goto done; + + error = got_object_id_by_path(&id, repo, commit, in_repo_path); if (error) { if (error->code != GOT_ERR_NO_TREE_ENTRY) goto done; @@ -6631,6 +6660,8 @@ done: if (error == NULL) error = close_err; } + if (commit) + got_object_commit_close(commit); if (worktree) got_worktree_close(worktree); free(id);
got_object_id_by_path() vs. commit object cache