commit a44927cc053de352796022400f27bce4522b407c from: Stefan Sperling date: Thu Apr 07 12:57:31 2022 UTC stop relying on commit cache for good performance of got_object_id_by_path() 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. ok op@ commit - c655fd934cee923423377833208cc041a67e4217 commit + a44927cc053de352796022400f27bce4522b407c blob - 36bd7fe005dea2816d23161fab0d7aed3b56e159 blob + 5cb9d726b7bc53a8da4e38d0bbf0697dd016ff87 --- 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) { @@ -11837,6 +11851,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; @@ -11921,9 +11936,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; @@ -11936,7 +11955,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; } @@ -11974,6 +11993,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 - a0286f156c9551904a9dfcbdfe00805bfe05bdf6 blob + 70b31ef68737cdd0d46bd944fea3af2c33d3e89a --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -4044,6 +4044,7 @@ gw_output_file_blame(struct gw_trans *gw_trans, struct const struct got_error *error = 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 *path = NULL, *in_repo_path = NULL; struct gw_blame_cb_args bca; @@ -4069,7 +4070,11 @@ gw_output_file_blame(struct gw_trans *gw_trans, struct if (error) goto done; - error = got_object_id_by_path(&obj_id, gw_trans->repo, commit_id, + error = got_object_open_as_commit(&commit, gw_trans->repo, commit_id); + if (error) + goto done; + + error = got_object_id_by_path(&obj_id, gw_trans->repo, commit, in_repo_path); if (error) goto done; @@ -4142,6 +4147,8 @@ done: } if (blob) got_object_blob_close(blob); + if (commit) + got_object_commit_close(commit); return error; } @@ -4151,6 +4158,7 @@ gw_output_blob_buf(struct gw_trans *gw_trans, struct g const struct got_error *error = 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 *path = NULL, *in_repo_path = NULL; int obj_type, set_mime = 0; @@ -4175,7 +4183,11 @@ gw_output_blob_buf(struct gw_trans *gw_trans, struct g if (error) goto done; - error = got_object_id_by_path(&obj_id, gw_trans->repo, commit_id, + error = got_object_open_as_commit(&commit, gw_trans->repo, commit_id); + if (error) + goto done; + + error = got_object_id_by_path(&obj_id, gw_trans->repo, commit, in_repo_path); if (error) goto done; @@ -4232,6 +4244,8 @@ done: free(path); if (blob) got_object_blob_close(blob); + if (commit) + got_object_commit_close(commit); if (error == NULL && kerr != KCGI_OK) error = gw_kcgi_error(kerr); return error; @@ -4243,6 +4257,7 @@ gw_output_repo_tree(struct gw_trans *gw_trans, struct const struct got_error *error = NULL; struct got_object_id *tree_id = NULL, *commit_id = NULL; struct got_tree_object *tree = NULL; + struct got_commit_object *commit = NULL; char *path = NULL, *in_repo_path = NULL; char *id_str = NULL; char *build_folder = NULL; @@ -4294,7 +4309,11 @@ gw_output_repo_tree(struct gw_trans *gw_trans, struct goto done; } - error = got_object_id_by_path(&tree_id, gw_trans->repo, commit_id, + error = got_object_open_as_commit(&commit, gw_trans->repo, commit_id); + if (error) + goto done; + + error = got_object_id_by_path(&tree_id, gw_trans->repo, commit, path); if (error) goto done; @@ -4466,6 +4485,8 @@ gw_output_repo_tree(struct gw_trans *gw_trans, struct done: if (tree) got_object_tree_close(tree); + if (commit) + got_object_commit_close(commit); free(id_str); free(href_blob); free(href_blame); 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); @@ -2643,6 +2643,11 @@ got_worktree_checkout_files(struct got_worktree *workt err = lock_worktree(worktree, LOCK_EX); 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) { @@ -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,12 +7833,18 @@ 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; @@ -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,15 +4329,20 @@ 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) @@ -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);