Commit Diff


commit - 4db73312461926de42eaa2bcc0758afa90f08b90
commit + 293f6400907ccfd03922756d5f2b6449afeada89
blob - 9c12562b41d068594598dd7102873581f5264862
blob + f801c050482a7b68f7052588f27d6151cc4cd72c
--- lib/blame.c
+++ lib/blame.c
@@ -35,6 +35,7 @@
 #include "got_lib_object.h"
 #include "got_lib_diff.h"
 #include "got_lib_diffoffset.h"
+#include "got_commit_graph.h"
 
 struct got_blame_line {
 	int annotated;
@@ -290,9 +291,9 @@ blame_open(struct got_blame **blamep, const char *path
 	struct got_object_id *obj_id = NULL;
 	struct got_blob_object *blob = NULL;
 	struct got_blame *blame = NULL;
-	struct got_commit_object *commit = NULL;
 	struct got_object_id *id = NULL;
 	int lineno;
+	struct got_commit_graph *graph = NULL;
 
 	*blamep = NULL;
 
@@ -335,55 +336,62 @@ blame_open(struct got_blame **blamep, const char *path
 
 	/* Loop over first-parent history and try to blame commits. */
 	/* TODO: Iterate commits via commit graph instead. */
-	err = got_object_open_as_commit(&commit, repo, start_commit_id);
+	err = got_commit_graph_open(&graph, start_commit_id, path, 0, repo);
 	if (err)
-		goto done;
-	id = got_object_id_dup(start_commit_id);
-	if (id == NULL) {
-		err = got_error_from_errno();
+		return err;
+	err = got_commit_graph_iter_start(graph, start_commit_id, repo);
+	if (err)
 		goto done;
-	}
-	while (1) {
-		struct got_object_qid *pid;
 
-		pid = SIMPLEQ_FIRST(&commit->parent_ids);
-		if (pid == NULL)
-			break;
-
-		err = blame_commit(blame, id, pid->id, path, repo, cb, arg);
+	id = NULL;
+	while (1) {
+		struct got_object_id *next_id;
+
+		err = got_commit_graph_iter_next(&next_id, graph);
 		if (err) {
-			if (err->code == GOT_ERR_ITER_COMPLETED)
+			if (err->code == GOT_ERR_ITER_COMPLETED) {
 				err = NULL;
+				break;
+			}
+			if (err->code != GOT_ERR_ITER_NEED_MORE)
+				break;
+			err = got_commit_graph_fetch_commits(graph, 1, repo);
+			if (err)
+				break;
+			else
+				continue;
+		}
+		if (next_id == NULL)
 			break;
+		if (id) {
+			err = blame_commit(blame, id, next_id, path, repo,
+			    cb, arg);
+			if (err) {
+				if (err->code == GOT_ERR_ITER_COMPLETED)
+					err = NULL;
+				break;
+			}
 		}
+		id = next_id;
+	}
 
-		free(id);
-		id = got_object_id_dup(pid->id);
-		if (id == NULL) {
-			err = got_error_from_errno();
-			goto done;
+	if (id) {
+		/* Annotate remaining non-annotated lines with last commit. */
+		for (lineno = 1; lineno <= blame->nlines; lineno++) {
+			err = annotate_line(blame, lineno, id, cb, arg);
+			if (err)
+				goto done;
 		}
-		got_object_commit_close(commit);
-		err = got_object_open_as_commit(&commit, repo, id);
-		if (err)
-			goto done;
 	}
 
-	/* Annotate remaining non-annotated lines with last commit. */
-	for (lineno = 1; lineno <= blame->nlines; lineno++) {
-		err = annotate_line(blame, lineno, id, cb, arg);
-		if (err)
-			goto done;
-	}
-
 done:
+	if (graph)
+		got_commit_graph_close(graph);
 	free(obj_id);
 	if (obj)
 		got_object_close(obj);
 	if (blob)
 		got_object_blob_close(blob);
-	if (commit)
-		got_object_commit_close(commit);
 	if (err) {
 		if (blame)
 			blame_close(blame);