Commit Diff


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);