Commit Diff


commit - 6402fb3cc1e54689a0b577e5958bf75a5a7e798b
commit + 27d434c2f27987c4eda331b3ab039198ccd6e101
blob - a506816c409702b75d36358f67e56799c415fb42
blob + 9a28bc62d6e087d451cafddb19e1b8e0eb71f2a8
--- got/got.c
+++ got/got.c
@@ -371,13 +371,12 @@ print_commit(struct got_commit_object *commit, struct 
 
 static const struct got_error *
 detect_change(int *changed, struct got_object_id *commit_id,
-    struct got_object *obj, const char *path, struct got_repository *repo)
+    struct got_object_id *obj_id, const char *path, struct got_repository *repo)
 {
 	const struct got_error *err = NULL;
-	struct got_object_id *id, *pid;
-	struct got_object *pobj;
+	struct got_object_id *obj_id2;
 
-	err = got_object_open_by_path(&pobj, repo, commit_id, path);
+	err = got_object_id_by_path(&obj_id2, repo, commit_id, path);
 	if (err) {
 		if (err->code != GOT_ERR_NO_OBJ)
 			return err;
@@ -385,10 +384,8 @@ detect_change(int *changed, struct got_object_id *comm
 		return NULL;
 	}
 
-	id = got_object_get_id(obj);
-	pid = got_object_get_id(pobj);
-	*changed = (got_object_id_cmp(id, pid) != 0);
-	got_object_close(pobj);
+	*changed = (got_object_id_cmp(obj_id, obj_id2) != 0);
+	free(obj_id2);
 	return NULL;
 }
 
@@ -435,11 +432,11 @@ print_commits(struct got_object *root_obj, struct got_
 		if (err)
 			break;
 		if (!is_root_path) {
-			struct got_object *obj;
+			struct got_object_id *obj_id = NULL;
 			struct got_object_qid *pid;
 			int changed = 0;
 
-			err = got_object_open_by_path(&obj, repo, id, path);
+			err = got_object_id_by_path(&obj_id, repo, id, path);
 			if (err) {
 				got_object_commit_close(commit);
 				if (err->code == GOT_ERR_NO_OBJ && found_obj) {
@@ -457,15 +454,15 @@ print_commits(struct got_object *root_obj, struct got_
 
 			pid = SIMPLEQ_FIRST(&commit->parent_ids);
 			if (pid) {
-				err = detect_change(&changed, pid->id, obj,
+				err = detect_change(&changed, pid->id, obj_id,
 				    path, repo);
 				if (err) {
-					got_object_close(obj);
+					free(obj_id);
 					got_object_commit_close(commit);
 					break;
 				}
 			}
-			got_object_close(obj);
+			free(obj_id);
 			if (!changed) {
 				got_object_commit_close(commit);
 				continue;
blob - 3b8ab2ca2d452058d45776035f263e51bf273ce6
blob + 14bfd3e594043bcdffe83875bce7da1b57a655e5
--- include/got_object.h
+++ include/got_object.h
@@ -100,6 +100,15 @@ struct got_object_id *got_object_get_id(struct got_obj
 const struct got_error *got_object_get_id_str(char **, struct got_object *);
 
 /*
+ * Get a newly allocated ID of the object which resides at the specified
+ * path in the tree of the specified commit.
+ * The caller should dispose of it with free(3).
+ */
+const struct got_error *
+got_object_id_by_path(struct got_object_id **, struct got_repository *,
+    struct got_object_id *, const char *);
+
+/*
  * Obtain the type of an object.
  * Returns one of the GOT_OBJ_TYPE_x values (see above).
  */
@@ -213,9 +222,5 @@ const struct got_error *
 got_object_open_as_blob(struct got_blob_object **,
     struct got_repository *, struct got_object_id *, size_t);
 
-const struct got_error *
-got_object_open_by_path(struct got_object **, struct got_repository *,
-    struct got_object_id *, const char *);
-
 const struct got_error *got_object_commit_add_parent(struct got_commit_object *,
     const char *);
blob - fdaf2c0601a2c589b3efba7bcec40bd4dd9135cb
blob + 80a7adc6bc2690d44ca7c113d7f7169ecbf616d0
--- lib/blame.c
+++ lib/blame.c
@@ -186,18 +186,24 @@ blame_commit(struct got_blame *blame, struct got_objec
 {
 	const struct got_error *err = NULL;
 	struct got_object *obj = NULL, *pobj = NULL;
+	struct got_object_id *obj_id = NULL, *pobj_id = NULL;
 	struct got_blob_object *blob = NULL, *pblob = NULL;
 	struct got_diff_changes *changes = NULL;
 
-	err = got_object_open_by_path(&obj, repo, id, path);
+	err = got_object_id_by_path(&obj_id, repo, id, path);
 	if (err)
 		goto done;
+
+	err = got_object_open(&obj, repo, obj_id);
+	if (err)
+		goto done;
+
 	if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) {
 		err = got_error(GOT_ERR_OBJ_TYPE);
 		goto done;
 	}
 
-	err = got_object_open_by_path(&pobj, repo, pid, path);
+	err = got_object_id_by_path(&pobj_id, repo, pid, path);
 	if (err) {
 		if (err->code == GOT_ERR_NO_OBJ) {
 			/* Blob's history began in previous commit. */
@@ -205,6 +211,18 @@ blame_commit(struct got_blame *blame, struct got_objec
 		}
 		goto done;
 	}
+
+	/* If IDs match then don't bother with diffing. */
+	if (got_object_id_cmp(obj_id, pobj_id) == 0) {
+		if (cb)
+			err = cb(arg, blame->nlines, -1, id);
+		goto done;
+	}
+
+	err = got_object_open(&pobj, repo, pobj_id);
+	if (err)
+		goto done;
+
 	if (got_object_get_type(pobj) != GOT_OBJ_TYPE_BLOB) {
 		/*
 		 * Encountered a non-blob at the path (probably a tree).
@@ -214,13 +232,6 @@ blame_commit(struct got_blame *blame, struct got_objec
 		goto done;
 	}
 
-	/* If blob hashes match then don't bother with diffing. */
-	if (got_object_id_cmp(&obj->id, &pobj->id) == 0) {
-		if (cb)
-			err = cb(arg, blame->nlines, -1, id);
-		goto done;
-	}
-
 	err = got_object_blob_open(&blob, repo, obj, 8192);
 	if (err)
 		goto done;
@@ -239,6 +250,8 @@ blame_commit(struct got_blame *blame, struct got_objec
 	} else if (cb)
 		err = cb(arg, blame->nlines, -1, id);
 done:
+	free(obj_id);
+	free(pobj_id);
 	if (obj)
 		got_object_close(obj);
 	if (pobj)
@@ -274,6 +287,7 @@ blame_open(struct got_blame **blamep, const char *path
 {
 	const struct got_error *err = NULL;
 	struct got_object *obj = NULL;
+	struct got_object_id *obj_id = NULL;
 	struct got_blob_object *blob = NULL;
 	struct got_blame *blame = NULL;
 	struct got_commit_object *commit = NULL;
@@ -282,9 +296,14 @@ blame_open(struct got_blame **blamep, const char *path
 
 	*blamep = NULL;
 
-	err = got_object_open_by_path(&obj, repo, start_commit_id, path);
+	err = got_object_id_by_path(&obj_id, repo, start_commit_id, path);
 	if (err)
 		return err;
+
+	err = got_object_open(&obj, repo, obj_id);
+	if (err)
+		goto done;
+
 	if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) {
 		err = got_error(GOT_ERR_OBJ_TYPE);
 		goto done;
@@ -357,7 +376,7 @@ blame_open(struct got_blame **blamep, const char *path
 	}
 
 done:
-	free(id);
+	free(obj_id);
 	if (obj)
 		got_object_close(obj);
 	if (blob)
blob - f3e4cc89ab7b9cd52cad9abd652fde93bb1bbcfb
blob + 927693e95c735d17314713b9b787e042828d89c1
--- lib/object.c
+++ lib/object.c
@@ -691,7 +691,7 @@ find_entry_by_name(struct got_tree_object *tree, const
 }
 
 const struct got_error *
-got_object_open_by_path(struct got_object **obj, struct got_repository *repo,
+got_object_id_by_path(struct got_object_id **id, struct got_repository *repo,
     struct got_object_id *commit_id, const char *path)
 {
 	const struct got_error *err = NULL;
@@ -701,7 +701,7 @@ got_object_open_by_path(struct got_object **obj, struc
 	char *seg, *s, *s0 = NULL;
 	size_t len = strlen(path);
 
-	*obj = NULL;
+	*id = NULL;
 
 	/* We are expecting an absolute in-repository path. */
 	if (path[0] != '/')
@@ -713,7 +713,9 @@ got_object_open_by_path(struct got_object **obj, struc
 
 	/* Handle opening of root of commit's tree. */
 	if (path[1] == '\0') {
-		err = got_object_open(obj, repo, commit->tree_id);
+		*id = got_object_id_dup(commit->tree_id);
+		if (*id == NULL)
+			err = got_error_from_errno();
 		goto done;
 	}
 
@@ -770,9 +772,11 @@ got_object_open_by_path(struct got_object **obj, struc
 		}
 	}
 
-	if (te)
-		err = got_object_open(obj, repo, te->id);
-	else
+	if (te) {
+		*id = got_object_id_dup(te->id);
+		if (*id == NULL)
+			return got_error_from_errno();
+	} else
 		err = got_error(GOT_ERR_NO_OBJ);
 done:
 	free(s0);
blob - 1e419f4ae1d5eb9ccc0b34b5c9bbf6c10ddae989
blob + 76613e9e4a6efe6647c06f0c12b58af00adc1656
--- tog/tog.c
+++ tog/tog.c
@@ -810,11 +810,11 @@ queue_commits(struct got_commit_graph *graph, struct c
 			break;
 
 		if (!is_root_path) {
-			struct got_object *obj;
+			struct got_object_id *obj_id = NULL;
 			struct got_object_qid *pid;
 			int changed = 0;
 
-			err = got_object_open_by_path(&obj, repo, id, path);
+			err = got_object_id_by_path(&obj_id, repo, id, path);
 			if (err) {
 				got_object_commit_close(commit);
 				if (err->code == GOT_ERR_NO_OBJ &&
@@ -828,27 +828,24 @@ queue_commits(struct got_commit_graph *graph, struct c
 
 			pid = SIMPLEQ_FIRST(&commit->parent_ids);
 			if (pid != NULL) {
-				struct got_object *pobj;
-				err = got_object_open_by_path(&pobj, repo,
+				struct got_object_id *pobj_id;
+				err = got_object_id_by_path(&pobj_id, repo,
 				    pid->id, path);
 				if (err) {
 					if (err->code != GOT_ERR_NO_OBJ) {
-						got_object_close(obj);
 						got_object_commit_close(commit);
+						free(obj_id);
 						break;
 					}
 					err = NULL;
 					changed = 1;
 				} else {
-					struct got_object_id *id, *pid;
-					id = got_object_get_id(obj);
-					pid = got_object_get_id(pobj);
-					changed =
-					    (got_object_id_cmp(id, pid) != 0);
-					got_object_close(pobj);
+					changed = (got_object_id_cmp(obj_id,
+					    pobj_id) != 0);
 				}
+				free(pobj_id);
 			}
-			got_object_close(obj);
+			free(obj_id);
 			if (!changed) {
 				got_object_commit_close(commit);
 				continue;
@@ -2098,11 +2095,17 @@ run_blame(struct tog_blame *blame, pthread_mutex_t *mu
 	const struct got_error *err = NULL;
 	struct got_blob_object *blob = NULL;
 	struct got_repository *thread_repo = NULL;
-	struct got_object *obj;
+	struct got_object_id *obj_id = NULL;
+	struct got_object *obj = NULL;
 
-	err = got_object_open_by_path(&obj, repo, commit_id, path);
+	err = got_object_id_by_path(&obj_id, repo, commit_id, path);
+	if (err)
+		goto done;
+
+	err = got_object_open(&obj, repo, obj_id);
 	if (err)
 		goto done;
+
 	if (got_object_get_type(obj) != GOT_OBJ_TYPE_BLOB) {
 		err = got_error(GOT_ERR_OBJ_TYPE);
 		goto done;
@@ -2163,6 +2166,7 @@ run_blame(struct tog_blame *blame, pthread_mutex_t *mu
 done:
 	if (blob)
 		got_object_blob_close(blob);
+	free(obj_id);
 	if (obj)
 		got_object_close(obj);
 	if (err)