commit 945f922947fbf90d4ae30e870a0d0262cf12bea8 from: Stefan Sperling via: Thomas Adam date: Sat Apr 16 08:06:59 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 - 7472ca4ef5ea6faebee012ddfbffd20fa9efddfb commit + 945f922947fbf90d4ae30e870a0d0262cf12bea8 blob - 277ccda9527fb4d2a732cdb084aa26a0db44e611 blob + 6629cdc24c5c18fdad568f4d00ff57c91a49268a --- 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 - bfcd04d64d489c45ea49ad7534c2e7289ee38820 blob + 12227984c432e81f5a1b01973031aec64920a2f6 --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -4043,6 +4043,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; @@ -4068,7 +4069,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; @@ -4141,6 +4146,8 @@ done: } if (blob) got_object_blob_close(blob); + if (commit) + got_object_commit_close(commit); return error; } @@ -4150,6 +4157,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; @@ -4174,7 +4182,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; @@ -4231,6 +4243,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; @@ -4242,6 +4256,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; @@ -4293,7 +4308,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; @@ -4465,6 +4484,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 - 311713a52724ce5002435a63acf53baaf1a6e61f blob + 34906057730bd12ea25ac3bb7f300ed8cac6ce46 --- lib/blame.c +++ lib/blame.c @@ -199,7 +199,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; @@ -215,7 +215,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; @@ -266,6 +270,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); @@ -497,6 +503,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; @@ -506,10 +513,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; @@ -620,6 +631,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 - e87849acb495b5499e6729f3d7fc1a01e4e11663 blob + 54a084ad975a8926ebfd7457ee7b7c3d144c9a8e --- lib/commit_graph.c +++ lib/commit_graph.c @@ -111,7 +111,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; @@ -292,20 +292,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 - 0d464f18b808fdf0b1f3e6807a54114f16b022c6 blob + ca30358a6647e506d86ee837489f03246816cf1d --- lib/object.c +++ lib/object.c @@ -1996,18 +1996,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); @@ -2020,8 +2015,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; @@ -2185,7 +2178,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]; @@ -2207,7 +2200,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) { @@ -2263,7 +2256,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; @@ -2273,7 +2266,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 - fbc8176eda96fecd3f552c89525ab6888296aa61 blob + 93bbd9e32f688c5cce6af6698e4027b2e7e4e875 --- lib/worktree.c +++ lib/worktree.c @@ -2456,7 +2456,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; @@ -2475,8 +2476,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; @@ -2490,8 +2491,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; @@ -2529,7 +2529,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); @@ -2640,6 +2640,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) { @@ -2650,7 +2655,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; @@ -3092,12 +3098,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; @@ -3122,7 +3132,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; @@ -3153,6 +3167,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) @@ -4541,6 +4559,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; @@ -4594,8 +4613,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 || @@ -4753,6 +4776,8 @@ done: if (tree) got_object_tree_close(tree); free(tree_id); + if (base_commit) + got_object_commit_close(base_commit); return err; } @@ -5510,6 +5535,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) { @@ -5520,8 +5546,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); @@ -5530,14 +5558,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; } @@ -6689,6 +6721,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; @@ -6697,6 +6730,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) @@ -6719,8 +6757,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; @@ -6755,6 +6793,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); @@ -7053,6 +7093,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; @@ -7060,6 +7101,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) @@ -7073,7 +7119,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; @@ -7266,6 +7312,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) @@ -7275,7 +7322,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; @@ -7317,6 +7368,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) @@ -7777,12 +7830,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; @@ -7816,6 +7875,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 - 27730ae459b928b0915680bfbb23bad789387ecd blob + 0c1f8bdddecfa08d332b9877c8b557307fcb4770 --- tog/tog.c +++ tog/tog.c @@ -1920,7 +1920,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; @@ -1969,7 +1969,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; @@ -2018,7 +2018,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 * @@ -4339,15 +4339,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) @@ -4415,6 +4420,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); @@ -4656,7 +4663,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; @@ -4671,8 +4678,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; @@ -4817,6 +4829,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; @@ -4902,8 +4915,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; @@ -4923,6 +4940,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) { @@ -5669,6 +5688,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; @@ -5755,6 +5775,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"); @@ -5764,7 +5788,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; @@ -6569,6 +6593,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; @@ -6612,7 +6637,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; @@ -6641,6 +6670,8 @@ done: if (error == NULL) error = close_err; } + if (commit) + got_object_commit_close(commit); if (worktree) got_worktree_close(worktree); free(id);