Commit 08d5d00056a7237bf6c60f85a6e72b7549cf9133

Vicent Marti 2010-05-18T20:55:19

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>

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__ */