Commit 7a1d6b72b6b0e351fb46965a7f46bc58b18e7cc8

Stefan Sperling 2020-01-15T19:10:46

fix 'tog log -c' with tags

diff --git a/got/got.c b/got/got.c
index 13fdc1d..5afeb71 100644
--- a/got/got.c
+++ b/got/got.c
@@ -956,39 +956,6 @@ done:
 }
 
 static const struct got_error *
-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 *
 cmd_checkout(int argc, char *argv[])
 {
 	const struct got_error *error = NULL;
@@ -1140,7 +1107,8 @@ cmd_checkout(int argc, char *argv[])
 
 	if (commit_id_str) {
 		struct got_object_id *commit_id;
-		error = resolve_commit_arg(&commit_id, commit_id_str, repo);
+		error = got_repo_resolve_commit_arg(&commit_id,
+		    commit_id_str, repo);
 		if (error)
 			goto done;
 		error = check_linear_ancestry(commit_id,
@@ -1379,7 +1347,8 @@ cmd_update(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = resolve_commit_arg(&commit_id, commit_id_str, repo);
+		error = got_repo_resolve_commit_arg(&commit_id,
+		    commit_id_str, repo);
 		free(commit_id_str);
 		commit_id_str = NULL;
 		if (error)
@@ -2722,7 +2691,8 @@ cmd_blame(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = resolve_commit_arg(&commit_id, commit_id_str, repo);
+		error = got_repo_resolve_commit_arg(&commit_id,
+		    commit_id_str, repo);
 		if (error)
 			goto done;
 	}
@@ -3026,7 +2996,8 @@ cmd_tree(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 	} else {
-		error = resolve_commit_arg(&commit_id, commit_id_str, repo);
+		error = got_repo_resolve_commit_arg(&commit_id,
+		    commit_id_str, repo);
 		if (error)
 			goto done;
 	}
@@ -3666,7 +3637,8 @@ cmd_branch(int argc, char *argv[])
 			commit_id_arg = worktree ?
 			    got_worktree_get_head_ref_name(worktree) :
 			    GOT_REF_HEAD;
-		error = resolve_commit_arg(&commit_id, commit_id_arg, repo);
+		error = got_repo_resolve_commit_arg(&commit_id,
+		    commit_id_arg, repo);
 		if (error)
 			goto done;
 		error = add_branch(repo, argv[0], commit_id);
@@ -7388,7 +7360,7 @@ cmd_cat(int argc, char *argv[])
 
 	if (commit_id_str == NULL)
 		commit_id_str = GOT_REF_HEAD;
-	error = resolve_commit_arg(&commit_id, commit_id_str, repo);
+	error = got_repo_resolve_commit_arg(&commit_id, commit_id_str, repo);
 	if (error)
 		goto done;
 
diff --git a/include/got_repository.h b/include/got_repository.h
index 6ef2a57..4255434 100644
--- a/include/got_repository.h
+++ b/include/got_repository.h
@@ -94,6 +94,14 @@ const struct got_error *got_repo_match_object_id_prefix(struct got_object_id **,
 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 d1f6708..6ab751c 100644
--- a/lib/repository.c
+++ b/lib/repository.c
@@ -1398,6 +1398,39 @@ 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 cb39099..6a748ce 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -1452,29 +1452,6 @@ queue_commits(struct got_commit_graph *graph, struct commit_queue *commits,
 }
 
 static const struct got_error *
-get_head_commit_id(struct got_object_id **head_id, const char *branch_name,
-    struct got_repository *repo)
-{
-	const struct got_error *err = NULL;
-	struct got_reference *head_ref;
-
-	*head_id = NULL;
-
-	err = got_ref_open(&head_ref, repo, branch_name, 0);
-	if (err)
-		return err;
-
-	err = got_ref_resolve(head_id, repo, head_ref);
-	got_ref_close(head_ref);
-	if (err) {
-		*head_id = NULL;
-		return err;
-	}
-
-	return NULL;
-}
-
-static const struct got_error *
 draw_commits(struct tog_view *view, struct commit_queue_entry **last,
     struct commit_queue_entry **selected, struct commit_queue_entry *first,
     struct commit_queue *commits, int selected_idx, int limit,
@@ -2410,8 +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 = get_head_commit_id(&start_id, s->head_ref_name ?
-		    s->head_ref_name : GOT_REF_HEAD, s->repo);
+		err = got_repo_resolve_commit_arg(&start_id,
+		    s->head_ref_name ?  s->head_ref_name : GOT_REF_HEAD,
+		    s->repo);
 		if (err) {
 			view_close(lv);
 			return err;
@@ -2592,18 +2570,12 @@ cmd_log(int argc, char *argv[])
 		goto done;
 
 	if (start_commit == NULL)
-		error = get_head_commit_id(&start_id, worktree ?
+		error = got_repo_resolve_commit_arg(&start_id, worktree ?
 		    got_worktree_get_head_ref_name(worktree) : GOT_REF_HEAD,
 		    repo);
-	else {
-		error = get_head_commit_id(&start_id, start_commit, repo);
-		if (error) {
-			if (error->code != GOT_ERR_NOT_REF)
-				goto done;
-			error = got_repo_match_object_id_prefix(&start_id,
-			    start_commit, GOT_OBJ_TYPE_COMMIT, repo);
-		}
-	}
+	else
+		error = got_repo_resolve_commit_arg(&start_id, start_commit,
+		    repo);
 	if (error != NULL)
 		goto done;
 
@@ -4250,13 +4222,8 @@ cmd_blame(int argc, char *argv[])
 		error = got_ref_resolve(&commit_id, repo, head_ref);
 		got_ref_close(head_ref);
 	} else {
-		error = get_head_commit_id(&commit_id, commit_id_str, repo);
-		if (error) {
-			if (error->code != GOT_ERR_NOT_REF)
-				goto done;
-			error = got_repo_match_object_id_prefix(&commit_id,
-			    commit_id_str, GOT_OBJ_TYPE_COMMIT, repo);
-		}
+		error = got_repo_resolve_commit_arg(&commit_id, commit_id_str,
+		    repo);
 	}
 	if (error != NULL)
 		goto done;
@@ -5043,17 +5010,8 @@ cmd_tree(int argc, char *argv[])
 	if (error)
 		goto done;
 
-	if (commit_id_arg == NULL)
-		error = get_head_commit_id(&commit_id, GOT_REF_HEAD, repo);
-	else {
-		error = get_head_commit_id(&commit_id, commit_id_arg, repo);
-		if (error) {
-			if (error->code != GOT_ERR_NOT_REF)
-				goto done;
-			error = got_repo_match_object_id_prefix(&commit_id,
-			    commit_id_arg, GOT_OBJ_TYPE_COMMIT, repo);
-		}
-	}
+	error = got_repo_resolve_commit_arg(&commit_id,
+	    commit_id_arg ? commit_id_arg : GOT_REF_HEAD, repo);
 	if (error != NULL)
 		goto done;