summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2010-05-22 14:32:59 +0200
committerAndreas Ericsson <ae@op5.se>2010-06-02 10:32:06 +0200
commit1a895dd787a5699c21d7925e9cdffa66f23605c4 (patch)
tree57b5df4e635d8324ca75b0dd33cb96271b426e23
parent8add01539268300564482f854412cfe9839e980c (diff)
downloadlibgit2-1a895dd787a5699c21d7925e9cdffa66f23605c4.tar.gz
Add arbritrary ordering revision walking.
The 'gitrp_next()' method now correctly does a revision walking of all the pushed revisions in arbritary ordering. Signed-off-by: Vicent Marti <tanoku@gmail.com> Signed-off-by: Andreas Ericsson <ae@op5.se>
-rw-r--r--src/commit.c15
-rw-r--r--src/commit.h1
-rw-r--r--src/git/commit.h8
-rw-r--r--src/revwalk.c62
-rw-r--r--src/revwalk.h1
5 files changed, 68 insertions, 19 deletions
diff --git a/src/commit.c b/src/commit.c
index fa33b5202..8654e891d 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -35,16 +35,15 @@ const git_oid *git_commit_id(git_commit *c)
return &c->id;
}
-void git_commit_mark_uninteresting(git_commit *commit)
+void git_commit__mark_uninteresting(git_commit *commit)
{
+ if (commit == NULL)
+ return;
+
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;
@@ -113,8 +112,6 @@ git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
git_oid_cpy(&commit->id, id);
commit->pool = pool;
- git_commit_list_insert(&pool->commits, commit);
-
return commit;
}
@@ -187,6 +184,10 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len)
if ((parent = git_commit_lookup(commit->pool, &oid)) == NULL)
return -1;
+ // Inherit uninteresting flag
+ if (commit->flags & GIT_COMMIT_HIDE)
+ parent->flags |= GIT_COMMIT_HIDE;
+
git_commit_list_insert(&commit->parents, parent);
}
diff --git a/src/commit.h b/src/commit.h
index 3a6b70664..a0c0512a8 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -29,6 +29,7 @@ struct git_commit {
int git_commit__parse_oid(git_oid *oid, char **buffer_out, const char *buffer_end, const char *header);
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__mark_uninteresting(git_commit *commit);
int git_commit_parse_existing(git_commit *commit);
diff --git a/src/git/commit.h b/src/git/commit.h
index 1a57ba732..279d8e376 100644
--- a/src/git/commit.h
+++ b/src/git/commit.h
@@ -44,6 +44,14 @@ GIT_EXTERN(git_commit *) git_commit_parse(git_revpool *pool, const git_oid *id);
*/
GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
+
+/**
+ * Mark a commit and all its parents as uninteresting.
+ * @param commit The commit to mark
+ */
+GIT_EXTERN(void) git_commit_mark_uninteresting(git_commit *commit);
+
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/revwalk.c b/src/revwalk.c
index fe6f9f293..001d938db 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -43,10 +43,12 @@ void gitrp_free(git_revpool *walk)
{
git_commit_list *list;
- list = walk->commits;
+ list = walk->roots;
while (list)
{
free(list->commit);
+ free(list);
+
list = list->next;
}
@@ -67,16 +69,35 @@ void gitrp_push(git_revpool *pool, git_commit *commit)
return;
}
+ // Sanity check: make sure that if the commit
+ // has been manually marked as uninteresting,
+ // all the parent commits are too.
+ if ((commit->flags & GIT_COMMIT_HIDE) != 0)
+ git_commit__mark_uninteresting(commit);
+
commit->flags |= GIT_COMMIT_SEEN;
git_commit_list_insert(&pool->roots, commit);
+ git_commit_list_insert(&pool->iterator, commit);
+}
+
+void gitrp_hide(git_revpool *pool, git_commit *commit)
+{
+ git_commit_mark_uninteresting(commit);
+ gitrp_push(pool, commit);
}
void gitrp_prepare_walk(git_revpool *pool)
{
- // TODO: sort commit list based on walk ordering
+ git_commit_list *list;
+
+ list = pool->roots;
+ while (list)
+ {
+ git_commit_list_insert(&pool->iterator, list->commit);
+ list = list->next;
+ }
- pool->iterator = pool->roots;
pool->walking = 1;
}
@@ -87,17 +108,36 @@ git_commit *gitrp_next(git_revpool *pool)
if (!pool->walking)
gitrp_prepare_walk(pool);
- // Iteration finished
- if (pool->iterator == NULL)
+ while (pool->iterator != NULL)
{
- gitrp_reset(pool);
- return NULL;
- }
+ git_commit_list *list;
+
+ next = pool->iterator->commit;
+ free(pool->iterator);
+ pool->iterator = pool->iterator->next;
+
+ list = next->parents;
+ while (list)
+ {
+ git_commit *parent = list->commit;
+ list = list->next;
- next = pool->iterator->commit;
- pool->iterator = pool->iterator->next;
+ if ((parent->flags & GIT_COMMIT_SEEN) != 0)
+ continue;
+
+ if (parent->parsed == 0)
+ git_commit_parse_existing(parent);
+
+ git_commit_list_insert(&pool->iterator, list->commit);
+ }
+
+ if ((next->flags & GIT_COMMIT_HIDE) != 0)
+ return next;
+ }
- return next;
+ // No commits left to iterate
+ gitrp_reset(pool);
+ return NULL;
}
void gitrp_reset(git_revpool *pool)
diff --git a/src/revwalk.h b/src/revwalk.h
index 34ff3378e..be01c4799 100644
--- a/src/revwalk.h
+++ b/src/revwalk.h
@@ -7,7 +7,6 @@
struct git_revpool {
git_odb *db;
git_commit_list *iterator;
- git_commit_list *commits;
git_commit_list *roots;
unsigned walking:1,