Add commit parents to parsed commits and commit lists to the revpool. Basic support for iterating the revpool. The following functions of the revwalk API have been partially implemented: void gitrp_reset(git_revpool *pool); void gitrp_push(git_revpool *pool, git_commit *commit); void gitrp_prepare_walk(git_revpool *pool); git_commit *gitrp_next(git_revpool *pool); Parsed commits' parents are now also parsed and stored in a "git_commit_list" structure (linked list). Signed-off-by: Vicent Marti <tanoku@gmail.com> Signed-off-by: Andreas Ericsson <ae@op5.se>
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
diff --git a/src/commit.c b/src/commit.c
index 1b30c5d..8844825 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -35,6 +35,22 @@ const git_oid *git_commit_id(git_commit *c)
return &c->id;
}
+void git_commit_mark_uninteresting(git_commit *commit)
+{
+ git_commit_list *parents = commit->parents;
+
+ commit->flags |= GIT_COMMIT_HIDE;
+
+ /*
+ * FIXME: mark recursively the parents' parents?
+ * They are most likely not parsed yet...
+ */
+ while (parents) {
+ parents->commit->flags |= GIT_COMMIT_HIDE;
+ parents = parents->next;
+ }
+}
+
git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
{
git_obj commit_obj;
@@ -141,7 +157,7 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len)
if ((parent = git_commit_lookup(commit->pool, &oid)) == NULL)
return -1;
- // TODO: push the new commit into the revpool
+ git_commit_list_insert(&commit->parents, parent);
}
if (git_commit__parse_time(&commit->commit_time, buffer, buffer_end) < 0)
@@ -152,3 +168,30 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len)
return 0;
}
+void git_commit_list_insert(git_commit_list **list, git_commit *commit)
+{
+ if (*list == NULL)
+ {
+ *list = git__malloc(sizeof(git_commit_list));
+
+ if (*list == NULL)
+ return;
+
+ (*list)->commit = commit;
+ (*list)->next = NULL;
+ }
+ else
+ {
+ git_commit_list *new_list = NULL;
+
+ new_list = git__malloc(sizeof(git_commit_list));
+
+ if (new_list == NULL)
+ return;
+
+ new_list->commit = commit;
+ new_list->next = *list;
+
+ *list = new_list;
+ }
+}
diff --git a/src/commit.h b/src/commit.h
index fe4db4d..7ab2d54 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -9,10 +9,19 @@
#define GIT_COMMIT_HIDE (1 << 1)
#define GIT_COMMIT_DELAY (1 << 2)
+struct git_commit_list {
+ struct git_commit *commit;
+ struct git_commit_list *next;
+};
+
+typedef struct git_commit_list git_commit_list;
+
struct git_commit {
git_oid id;
time_t commit_time;
git_revpool *pool;
+ git_commit_list *parents;
+
unsigned parsed:1,
flags:26;
};
@@ -21,4 +30,6 @@ int git_commit__parse_oid(git_oid *oid, char **buffer_out, const char *buffer_en
int git_commit__parse_buffer(git_commit *commit, void *data, size_t len);
int git_commit__parse_time(time_t *commit_time, char *buffer, const char *buffer_end);
+void git_commit_list_insert(git_commit_list **list, git_commit *commit);
+
#endif
diff --git a/src/revwalk.c b/src/revwalk.c
index 11261fb..96f3444 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -24,6 +24,7 @@
*/
#include "common.h"
+#include "commit.h"
#include "revwalk.h"
git_revpool *gitrp_alloc(git_odb *db)
@@ -32,6 +33,8 @@ git_revpool *gitrp_alloc(git_odb *db)
if (!walk)
return NULL;
+ memset(walk, 0x0, sizeof(git_revpool));
+
walk->db = db;
return walk;
}
@@ -40,3 +43,54 @@ void gitrp_free(git_revpool *walk)
{
free(walk);
}
+
+void gitrp_push(git_revpool *pool, git_commit *commit)
+{
+ if ((commit->flags & GIT_COMMIT_SEEN) != 0)
+ return;
+
+ /* FIXME:
+ * Unparsed commit objects? Where do these come from?
+ * Do we need to handle them?
+ */
+ if (!commit->parsed)
+ return;
+
+ commit->flags |= GIT_COMMIT_SEEN;
+
+ git_commit_list_insert(&pool->commits, commit);
+}
+
+void gitrp_prepare_walk(git_revpool *pool)
+{
+ // TODO: sort commit list based on walk ordering
+
+ pool->iterator = pool->commits;
+ pool->walking = 1;
+}
+
+git_commit *gitrp_next(git_revpool *pool)
+{
+ git_commit *next;
+
+ if (!pool->walking)
+ gitrp_prepare_walk(pool);
+
+ // Iteration finished
+ if (pool->iterator == NULL)
+ {
+ gitrp_reset(pool);
+ return NULL;
+ }
+
+ next = pool->iterator->commit;
+ pool->iterator = pool->iterator->next;
+
+ return next;
+}
+
+void gitrp_reset(git_revpool *pool)
+{
+ pool->iterator = NULL;
+ pool->walking = 0;
+}
diff --git a/src/revwalk.h b/src/revwalk.h
index 2ef4e5d..edf57b4 100644
--- a/src/revwalk.h
+++ b/src/revwalk.h
@@ -6,6 +6,11 @@
struct git_revpool {
git_odb *db;
+ git_commit_list *iterator;
+ git_commit_list *commits;
+
+ unsigned walking:1,
+ topological_sort:1;
};
#endif /* INCLUDE_revwalk_h__ */