Commit 71a276322e39e17baf5697b5daac8e8fe6ad2ae1

Stefan Sperling 2020-01-15T19:26:49

move match_object_id() into the library; supersedes got_repo_resolve_commit_arg

diff --git a/got/got.c b/got/got.c
index 5afeb71..8557a12 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1107,8 +1107,8 @@ cmd_checkout(int argc, char *argv[])
 
 	if (commit_id_str) {
 		struct got_object_id *commit_id;
-		error = got_repo_resolve_commit_arg(&commit_id,
-		    commit_id_str, repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 		if (error)
 			goto done;
 		error = check_linear_ancestry(commit_id,
@@ -1347,8 +1347,8 @@ cmd_update(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = got_repo_resolve_commit_arg(&commit_id,
-		    commit_id_str, repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 		free(commit_id_str);
 		commit_id_str = NULL;
 		if (error)
@@ -2190,66 +2190,6 @@ done:
 }
 
 static const struct got_error *
-match_object_id(struct got_object_id **id, char **label,
-    const char *id_str, int obj_type, int resolve_tags,
-    struct got_repository *repo)
-{
-	const struct got_error *err;
-	struct got_tag_object *tag;
-	struct got_reference *ref = NULL;
-
-	*id = NULL;
-	*label = NULL;
-
-	if (resolve_tags) {
-		err = got_repo_object_match_tag(&tag, id_str, GOT_OBJ_TYPE_ANY,
-		    repo);
-		if (err == NULL) {
-			*id = got_object_id_dup(
-			    got_object_tag_get_object_id(tag));
-			if (*id == NULL)
-				err = got_error_from_errno("got_object_id_dup");
-			else if (asprintf(label, "refs/tags/%s",
-			    got_object_tag_get_name(tag)) == -1) {
-				err = got_error_from_errno("asprintf");
-				free(*id);
-				*id = NULL;
-			}
-			got_object_tag_close(tag);
-			return err;
-		} else if (err->code != GOT_ERR_OBJ_TYPE &&
-		    err->code != GOT_ERR_NO_OBJ)
-			return err;
-	}
-
-	err = got_repo_match_object_id_prefix(id, id_str, obj_type, repo);
-	if (err) {
-		if (err->code != GOT_ERR_BAD_OBJ_ID_STR)
-			return err;
-		err = got_ref_open(&ref, repo, id_str, 0);
-		if (err != NULL)
-			goto done;
-		*label = strdup(got_ref_get_name(ref));
-		if (*label == NULL) {
-			err = got_error_from_errno("strdup");
-			goto done;
-		}
-		err = got_ref_resolve(id, repo, ref);
-	} else {
-		err = got_object_id_str(label, *id);
-		if (*label == NULL) {
-			err = got_error_from_errno("strdup");
-			goto done;
-		}
-	}
-done:
-	if (ref)
-		got_ref_close(ref);
-	return err;
-}
-
-
-static const struct got_error *
 cmd_diff(int argc, char *argv[])
 {
 	const struct got_error *error;
@@ -2396,13 +2336,13 @@ cmd_diff(int argc, char *argv[])
 		goto done;
 	}
 
-	error = match_object_id(&id1, &label1, id_str1, GOT_OBJ_TYPE_ANY, 1,
-	    repo);
+	error = got_repo_match_object_id(&id1, &label1, id_str1,
+	    GOT_OBJ_TYPE_ANY, 1, repo);
 	if (error)
 		goto done;
 
-	error = match_object_id(&id2, &label2, id_str2, GOT_OBJ_TYPE_ANY, 1,
-	    repo);
+	error = got_repo_match_object_id(&id2, &label2, id_str2,
+	    GOT_OBJ_TYPE_ANY, 1, repo);
 	if (error)
 		goto done;
 
@@ -2691,8 +2631,8 @@ cmd_blame(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = got_repo_resolve_commit_arg(&commit_id,
-		    commit_id_str, repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 		if (error)
 			goto done;
 	}
@@ -2996,8 +2936,8 @@ cmd_tree(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = got_repo_resolve_commit_arg(&commit_id,
-		    commit_id_str, repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 		if (error)
 			goto done;
 	}
@@ -3637,8 +3577,8 @@ cmd_branch(int argc, char *argv[])
 			commit_id_arg = worktree ?
 			    got_worktree_get_head_ref_name(worktree) :
 			    GOT_REF_HEAD;
-		error = got_repo_resolve_commit_arg(&commit_id,
-		    commit_id_arg, repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_arg, GOT_OBJ_TYPE_COMMIT, 1, repo);
 		if (error)
 			goto done;
 		error = add_branch(repo, argv[0], commit_id);
@@ -3978,7 +3918,7 @@ add_tag(struct got_repository *repo, const char *tag_name,
 	if (err)
 		return err;
 
-	err = match_object_id(&commit_id, &label, commit_arg,
+	err = got_repo_match_object_id(&commit_id, &label, commit_arg,
 	    GOT_OBJ_TYPE_COMMIT, 1, repo);
 	if (err)
 		goto done;
@@ -7360,7 +7300,8 @@ cmd_cat(int argc, char *argv[])
 
 	if (commit_id_str == NULL)
 		commit_id_str = GOT_REF_HEAD;
-	error = got_repo_resolve_commit_arg(&commit_id, commit_id_str, repo);
+	error = got_repo_match_object_id(&commit_id, NULL,
+	    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 	if (error)
 		goto done;
 
@@ -7371,7 +7312,7 @@ cmd_cat(int argc, char *argv[])
 			if (error)
 				break;
 		} else {
-			error = match_object_id(&id, &label, argv[i],
+			error = got_repo_match_object_id(&id, &label, argv[i],
 			    GOT_OBJ_TYPE_ANY, 0, repo);
 			if (error) {
 				if (error->code != GOT_ERR_BAD_OBJ_ID_STR &&
diff --git a/include/got_repository.h b/include/got_repository.h
index 4255434..f54c896 100644
--- a/include/got_repository.h
+++ b/include/got_repository.h
@@ -88,20 +88,24 @@ const struct got_error *got_repo_match_object_id_prefix(struct got_object_id **,
     const char *, int, struct got_repository *);
 
 /*
+ * Given an object ID string or reference name, attempt to find a corresponding
+ * commit object. Tags can optionally be ignored during matching.
+ * The object type may be restricted to commit, tree, blob, or tag.
+ * GOT_OBJ_TYPE_ANY will match any type of object.
+ * A human-readable label can optionally be returned, which the caller should
+ * dispose of with free(3).
+ * Return GOT_ERR_NO_OBJ if no matching commit can be found.
+ */
+const struct got_error *got_repo_match_object_id(struct got_object_id **,
+    char **, const char *, int, int, struct got_repository *);
+
+/*
  * Attempt to find a tag object with a given name and target object type.
  * Return GOT_ERR_NO_OBJ if no matching tag can be found.
  */
 const struct got_error *got_repo_object_match_tag(struct got_tag_object **,
     const char *, int, struct got_repository *);
 
-/*
- * Given an object ID string or reference name argument,
- * attempt to find a corresponding commit object.
- * Return GOT_ERR_NO_OBJ if no matching commit can be found.
- */
-const struct got_error *got_repo_resolve_commit_arg(struct got_object_id **,
-    const char *, struct got_repository *);
-
 /* A callback function which is invoked when a path is imported. */
 typedef const struct got_error *(*got_repo_import_cb)(void *, const char *);
 
diff --git a/lib/repository.c b/lib/repository.c
index 6ab751c..694024d 100644
--- a/lib/repository.c
+++ b/lib/repository.c
@@ -1355,6 +1355,68 @@ done:
 }
 
 const struct got_error *
+got_repo_match_object_id(struct got_object_id **id, char **label,
+    const char *id_str, int obj_type, int resolve_tags,
+    struct got_repository *repo)
+{
+	const struct got_error *err;
+	struct got_tag_object *tag;
+	struct got_reference *ref = NULL;
+
+	*id = NULL;
+	if (label)
+		*label = NULL;
+
+	if (resolve_tags) {
+		err = got_repo_object_match_tag(&tag, id_str, GOT_OBJ_TYPE_ANY,
+		    repo);
+		if (err == NULL) {
+			*id = got_object_id_dup(
+			    got_object_tag_get_object_id(tag));
+			if (*id == NULL)
+				err = got_error_from_errno("got_object_id_dup");
+			else if (label && asprintf(label, "refs/tags/%s",
+			    got_object_tag_get_name(tag)) == -1) {
+				err = got_error_from_errno("asprintf");
+				free(*id);
+				*id = NULL;
+			}
+			got_object_tag_close(tag);
+			return err;
+		} else if (err->code != GOT_ERR_OBJ_TYPE &&
+		    err->code != GOT_ERR_NO_OBJ)
+			return err;
+	}
+
+	err = got_repo_match_object_id_prefix(id, id_str, obj_type, repo);
+	if (err) {
+		if (err->code != GOT_ERR_BAD_OBJ_ID_STR)
+			return err;
+		err = got_ref_open(&ref, repo, id_str, 0);
+		if (err != NULL)
+			goto done;
+		if (label) {
+			*label = strdup(got_ref_get_name(ref));
+			if (*label == NULL) {
+				err = got_error_from_errno("strdup");
+				goto done;
+			}
+		}
+		err = got_ref_resolve(id, repo, ref);
+	} else if (label) {
+		err = got_object_id_str(label, *id);
+		if (*label == NULL) {
+			err = got_error_from_errno("strdup");
+			goto done;
+		}
+	}
+done:
+	if (ref)
+		got_ref_close(ref);
+	return err;
+}
+
+const struct got_error *
 got_repo_object_match_tag(struct got_tag_object **tag, const char *name,
     int obj_type, struct got_repository *repo)
 {
@@ -1398,39 +1460,6 @@ got_repo_object_match_tag(struct got_tag_object **tag, const char *name,
 	return err;
 }
 
-const struct got_error *
-got_repo_resolve_commit_arg(struct got_object_id **commit_id,
-    const char *commit_id_arg, struct got_repository *repo)
-{
-	const struct got_error *err;
-	struct got_reference *ref;
-	struct got_tag_object *tag;
-
-	err = got_repo_object_match_tag(&tag, commit_id_arg,
-	    GOT_OBJ_TYPE_COMMIT, repo);
-	if (err == NULL) {
-		*commit_id = got_object_id_dup(
-		    got_object_tag_get_object_id(tag));
-		if (*commit_id == NULL)
-			err = got_error_from_errno("got_object_id_dup");
-		got_object_tag_close(tag);
-		return err;
-	} else if (err->code != GOT_ERR_NO_OBJ)
-		return err;
-
-	err = got_ref_open(&ref, repo, commit_id_arg, 0);
-	if (err == NULL) {
-		err = got_ref_resolve(commit_id, repo, ref);
-		got_ref_close(ref);
-	} else {
-		if (err->code != GOT_ERR_NOT_REF)
-			return err;
-		err = got_repo_match_object_id_prefix(commit_id,
-		    commit_id_arg, GOT_OBJ_TYPE_COMMIT, repo);
-	}
-	return err;
-}
-
 static const struct got_error *
 alloc_added_blob_tree_entry(struct got_tree_entry **new_te,
     const char *name, mode_t mode, struct got_object_id *blob_id)
diff --git a/tog/tog.c b/tog/tog.c
index 6a748ce..ac26de5 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -2387,9 +2387,9 @@ input_log_view(struct tog_view **new_view, struct tog_view **dead_view,
 		    view->begin_y, view->begin_x, TOG_VIEW_LOG);
 		if (lv == NULL)
 			return got_error_from_errno("view_open");
-		err = got_repo_resolve_commit_arg(&start_id,
-		    s->head_ref_name ?  s->head_ref_name : GOT_REF_HEAD,
-		    s->repo);
+		err = got_repo_match_object_id(&start_id, NULL,
+		    s->head_ref_name ? s->head_ref_name : GOT_REF_HEAD,
+		    GOT_OBJ_TYPE_COMMIT, 1, s->repo);
 		if (err) {
 			view_close(lv);
 			return err;
@@ -2570,12 +2570,12 @@ cmd_log(int argc, char *argv[])
 		goto done;
 
 	if (start_commit == NULL)
-		error = got_repo_resolve_commit_arg(&start_id, worktree ?
+		error = got_repo_match_object_id(&start_id, NULL, worktree ?
 		    got_worktree_get_head_ref_name(worktree) : GOT_REF_HEAD,
-		    repo);
+		    GOT_OBJ_TYPE_COMMIT, 1, repo);
 	else
-		error = got_repo_resolve_commit_arg(&start_id, start_commit,
-		    repo);
+		error = got_repo_match_object_id(&start_id, NULL, start_commit,
+		    GOT_OBJ_TYPE_COMMIT, 1, repo);
 	if (error != NULL)
 		goto done;
 
@@ -4222,8 +4222,8 @@ cmd_blame(int argc, char *argv[])
 		error = got_ref_resolve(&commit_id, repo, head_ref);
 		got_ref_close(head_ref);
 	} else {
-		error = got_repo_resolve_commit_arg(&commit_id, commit_id_str,
-		    repo);
+		error = got_repo_match_object_id(&commit_id, NULL,
+		    commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo);
 	}
 	if (error != NULL)
 		goto done;
@@ -5010,8 +5010,9 @@ cmd_tree(int argc, char *argv[])
 	if (error)
 		goto done;
 
-	error = got_repo_resolve_commit_arg(&commit_id,
-	    commit_id_arg ? commit_id_arg : GOT_REF_HEAD, repo);
+	error = got_repo_match_object_id(&commit_id, NULL,
+	    commit_id_arg ? commit_id_arg : GOT_REF_HEAD,
+	    GOT_OBJ_TYPE_COMMIT, 1, repo);
 	if (error != NULL)
 		goto done;