make 'blame' traverse history via commit graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
diff --git a/lib/blame.c b/lib/blame.c
index 9c12562..f801c05 100644
--- a/lib/blame.c
+++ b/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)
+ return err;
+ err = got_commit_graph_iter_start(graph, start_commit_id, repo);
if (err)
goto done;
- id = got_object_id_dup(start_commit_id);
- if (id == NULL) {
- err = got_error_from_errno();
- goto done;
- }
- while (1) {
- struct got_object_qid *pid;
- pid = SIMPLEQ_FIRST(&commit->parent_ids);
- if (pid == NULL)
- break;
+ id = NULL;
+ while (1) {
+ struct got_object_id *next_id;
- err = blame_commit(blame, id, pid->id, path, repo, cb, arg);
+ 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;
+ break;
+ }
+ if (err->code != GOT_ERR_ITER_NEED_MORE)
+ break;
+ err = got_commit_graph_fetch_commits(graph, 1, repo);
+ if (err)
+ break;
+ else
+ continue;
}
-
- free(id);
- id = got_object_id_dup(pid->id);
- if (id == NULL) {
- err = got_error_from_errno();
- goto done;
+ 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;
+ }
}
- got_object_commit_close(commit);
- err = got_object_open_as_commit(&commit, repo, id);
- if (err)
- goto done;
+ id = next_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;
+ 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;
+ }
}
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);