Commit 27d434c2f27987c4eda331b3ab039198ccd6e101

Stefan Sperling 2018-09-15T13:52:06

replace got_object_open_by_path() with got_object_id_by_path()

diff --git a/got/got.c b/got/got.c
index a506816..9a28bc6 100644
--- a/got/got.c
+++ b/got/got.c
@@ -371,13 +371,12 @@ print_commit(struct got_commit_object *commit, struct got_object_id *id,
 
 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 *commit_id,
 		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_object_id *root_id,
 		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_object_id *root_id,
 
 			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;
diff --git a/include/got_object.h b/include/got_object.h
index 3b8ab2c..14bfd3e 100644
--- a/include/got_object.h
+++ b/include/got_object.h
@@ -100,6 +100,15 @@ struct got_object_id *got_object_get_id(struct got_object *);
 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 *);
diff --git a/lib/blame.c b/lib/blame.c
index fdaf2c0..80a7adc 100644
--- a/lib/blame.c
+++ b/lib/blame.c
@@ -186,18 +186,24 @@ blame_commit(struct got_blame *blame, struct got_object_id *id,
 {
 	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_object_id *id,
 		}
 		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_object_id *id,
 		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_object_id *id,
 	} 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)
diff --git a/lib/object.c b/lib/object.c
index f3e4cc8..927693e 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -691,7 +691,7 @@ find_entry_by_name(struct got_tree_object *tree, const char *name)
 }
 
 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, struct got_repository *repo,
 	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, struct got_repository *repo,
 
 	/* 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, struct got_repository *repo,
 		}
 	}
 
-	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);
diff --git a/tog/tog.c b/tog/tog.c
index 1e419f4..76613e9 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -810,11 +810,11 @@ queue_commits(struct got_commit_graph *graph, struct commit_queue *commits,
 			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 commit_queue *commits,
 
 			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 *mutex,
 	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 *mutex,
 done:
 	if (blob)
 		got_object_blob_close(blob);
+	free(obj_id);
 	if (obj)
 		got_object_close(obj);
 	if (err)