Commit 1a895dd7 by Vicent Marti Committed by Andreas Ericsson

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>
parent 8add0153
......@@ -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);
}
......
......@@ -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);
......
......@@ -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
......@@ -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)
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment