libgit2/src/revwalk.c
Ramsay Jones f29249340c Style: Do not use (C99) // comments
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Andreas Ericsson <ae@op5.se>
2010-06-02 11:18:56 +02:00

187 lines
4.2 KiB
C

/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "common.h"
#include "commit.h"
#include "revwalk.h"
static const int default_table_size = 32;
git_revpool *gitrp_alloc(git_odb *db)
{
git_revpool *walk = git__malloc(sizeof(*walk));
if (!walk)
return NULL;
memset(walk, 0x0, sizeof(git_revpool));
walk->commits = git_revpool_table_create(default_table_size);
walk->db = db;
return walk;
}
void gitrp_free(git_revpool *walk)
{
git_commit_list_clear(&(walk->iterator), 0);
git_commit_list_clear(&(walk->roots), 0);
git_revpool_table_free(walk->commits);
free(walk);
}
void gitrp_sorting(git_revpool *pool, unsigned int sort_mode)
{
if (pool->walking)
return;
pool->sorting = sort_mode;
gitrp_reset(pool);
}
int gitrp_push(git_revpool *pool, git_commit *commit)
{
if (commit == NULL || commit->seen)
return GIT_ENOTFOUND;
if (commit->object.pool != pool || pool->walking)
return GIT_ERROR;
if (!commit->parsed) {
int error = git_commit_parse_existing(commit);
if (error < 0)
return error;
}
/*
* Sanity check: make sure that if the commit
* has been manually marked as uninteresting,
* all the parent commits are too.
*/
if (commit->uninteresting)
git_commit__mark_uninteresting(commit);
if (git_commit_list_push_back(&pool->roots, commit) < 0)
return GIT_ENOMEM;
return 0;
}
int gitrp_hide(git_revpool *pool, git_commit *commit)
{
if (pool->walking)
return GIT_ERROR;
git_commit__mark_uninteresting(commit);
return gitrp_push(pool, commit);
}
int gitrp__enroot(git_revpool *pool, git_commit *commit)
{
int error;
git_commit_node *parents;
if (commit->seen)
return 0;
if (commit->parsed == 0) {
error = git_commit_parse_existing(commit);
if (error < 0)
return error;
}
commit->seen = 1;
for (parents = commit->parents.head; parents != NULL; parents = parents->next) {
parents->commit->in_degree++;
error = gitrp__enroot(pool, parents->commit);
if (error < 0)
return error;
}
if (git_commit_list_push_back(&pool->iterator, commit))
return GIT_ENOMEM;
return 0;
}
void gitrp__prepare_walk(git_revpool *pool)
{
git_commit_node *it;
for (it = pool->roots.head; it != NULL; it = it->next)
gitrp__enroot(pool, it->commit);
if (pool->sorting & GIT_RPSORT_TIME)
git_commit_list_timesort(&pool->iterator);
if (pool->sorting & GIT_RPSORT_TOPOLOGICAL)
git_commit_list_toposort(&pool->iterator);
if (pool->sorting & GIT_RPSORT_REVERSE)
pool->next_commit = &git_commit_list_pop_back;
else
pool->next_commit = &git_commit_list_pop_front;
pool->walking = 1;
}
git_commit *gitrp_next(git_revpool *pool)
{
git_commit *next;
if (!pool->walking)
gitrp__prepare_walk(pool);
while ((next = pool->next_commit(&pool->iterator)) != NULL) {
if (!next->uninteresting)
return next;
}
/* No commits left to iterate */
gitrp_reset(pool);
return NULL;
}
void gitrp_reset(git_revpool *pool)
{
git_commit *commit;
git_revpool_tableit it;
git_revpool_tableit_init(pool->commits, &it);
while ((commit = (git_commit *)git_revpool_tableit_next(&it)) != NULL) {
commit->seen = 0;
commit->topo_delay = 0;
commit->in_degree = 0;
}
git_commit_list_clear(&pool->iterator, 0);
pool->walking = 0;
}