Commit abd2672ad512810199886aa5cc285df04f1aed67

Stefan Sperling 2018-12-23T11:36:31

move commit header printing in diffs out of the library

diff --git a/lib/diff.c b/lib/diff.c
index be49c12..314a740 100644
--- a/lib/diff.c
+++ b/lib/diff.c
@@ -587,16 +587,6 @@ done:
 	return err;
 }
 
-static char *
-get_datestr(time_t *time, char *datebuf)
-{
-	char *p, *s = ctime_r(time, datebuf);
-	p = strchr(s, '\n');
-	if (p)
-		*p = '\0';
-	return s;
-}
-
 const struct got_error *
 got_diff_objects_as_commits(struct got_object *obj1, struct got_object *obj2,
     int diff_context, struct got_repository *repo, FILE *outfile)
@@ -604,8 +594,6 @@ got_diff_objects_as_commits(struct got_object *obj1, struct got_object *obj2,
 	const struct got_error *err;
 	struct got_commit_object *commit1 = NULL, *commit2 = NULL;
 	struct got_object *tree_obj1  = NULL, *tree_obj2 = NULL;
-	char *id_str;
-	char datebuf[26];
 
 	if (obj2 == NULL)
 		return got_error(GOT_ERR_NO_OBJ);
@@ -625,33 +613,6 @@ got_diff_objects_as_commits(struct got_object *obj1, struct got_object *obj2,
 	err = got_object_open(&tree_obj2, repo, commit2->tree_id);
 	if (err)
 		goto done;
-	err = got_object_get_id_str(&id_str, obj2);
-	if (err)
-		goto done;
-	if (fprintf(outfile, "commit: %s\n", id_str) < 0) {
-		err = got_error_from_errno();
-		free(id_str);
-		goto done;
-	}
-	free(id_str);
-	if (fprintf(outfile, "from: %s\n", commit2->author) < 0) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	if (fprintf(outfile, "date: %s UTC\n",
-	    get_datestr(&commit2->committer_time, datebuf)) < 0) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	if (strcmp(commit2->author, commit2->committer) != 0 &&
-	    fprintf(outfile, "via: %s\n", commit2->committer) < 0) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	if (fprintf(outfile, "%s\n", commit2->logmsg) < 0) {
-		err = got_error_from_errno();
-		goto done;
-	}
 
 	err = got_diff_objects_as_trees(tree_obj1, tree_obj2, "", "",
 	    diff_context, repo, outfile);
diff --git a/tog/tog.c b/tog/tog.c
index a450bfd..c21e546 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -1812,6 +1812,60 @@ draw_file(struct tog_view *view, FILE *f, int *first_displayed_line,
 	return NULL;
 }
 
+static char *
+get_datestr(time_t *time, char *datebuf)
+{
+	char *p, *s = ctime_r(time, datebuf);
+	p = strchr(s, '\n');
+	if (p)
+		*p = '\0';
+	return s;
+}
+
+static const struct got_error *
+write_commit_info(struct got_object *obj, struct got_repository *repo,
+    FILE *outfile)
+{
+	const struct got_error *err = NULL;
+	char *id_str;
+	char datebuf[26];
+	struct got_commit_object *commit = NULL;
+
+	err = got_object_id_str(&id_str, got_object_get_id(obj));
+	if (err)
+		return err;
+
+	err = got_object_commit_open(&commit, repo, obj);
+
+	if (fprintf(outfile, "commit: %s\n", id_str) < 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	if (fprintf(outfile, "from: %s\n", commit->author) < 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	if (fprintf(outfile, "date: %s UTC\n",
+	    get_datestr(&commit->committer_time, datebuf)) < 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	if (strcmp(commit->author, commit->committer) != 0 &&
+	    fprintf(outfile, "via: %s\n", commit->committer) < 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	if (fprintf(outfile, "%s\n", commit->logmsg) < 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+done:
+	free(id_str);
+	if (commit)
+		got_object_commit_close(commit);
+	return err;
+}
+
 static const struct got_error *
 create_diff(struct tog_diff_view_state *s)
 {
@@ -1847,10 +1901,27 @@ create_diff(struct tog_diff_view_state *s)
 		err = got_diff_objects_as_trees(obj1, obj2, "", "",
 		    s->diff_context, s->repo, f);
 		break;
-	case GOT_OBJ_TYPE_COMMIT:
+	case GOT_OBJ_TYPE_COMMIT: {
+		struct got_object_qid *pid;
+		struct got_commit_object *commit2;
+
+		err = got_object_commit_open(&commit2, s->repo, obj2);
+		if (err)
+			break;
+		/* Show commit info if we're diffing to a parent commit. */
+		SIMPLEQ_FOREACH(pid, &commit2->parent_ids, entry) {
+			struct got_object_id *id1 = got_object_get_id(obj1);
+			if (got_object_id_cmp(id1, pid->id) == 0) {
+				write_commit_info(obj2, s->repo, f);
+				break;
+			}
+		}
+		got_object_commit_close(commit2);
+
 		err = got_diff_objects_as_commits(obj1, obj2, s->diff_context,
 		    s->repo, f);
 		break;
+	}
 	default:
 		err = got_error(GOT_ERR_OBJ_TYPE);
 		break;