Add 'git_revpool_object' and 'git_revpool_table' structures.
[libgit2.git] / src / revwalk.c
blobcbf7144d8b79387bb97f115273515b9453e94b2f
1 /*
2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
26 #include "common.h"
27 #include "commit.h"
28 #include "revwalk.h"
30 git_revpool *gitrp_alloc(git_odb *db)
32 git_revpool *walk = git__malloc(sizeof(*walk));
33 if (!walk)
34 return NULL;
36 memset(walk, 0x0, sizeof(git_revpool));
38 walk->db = db;
39 return walk;
42 void gitrp_free(git_revpool *walk)
44 git_commit_list_clear(&(walk->iterator), 0);
45 git_commit_list_clear(&(walk->roots), 1);
46 free(walk);
49 void gitrp_push(git_revpool *pool, git_commit *commit)
51 if (commit->object.pool != pool)
52 return;
54 if (commit->seen)
55 return;
57 if (!commit->parsed)
59 if (git_commit_parse_existing(commit) < 0)
60 return;
63 // Sanity check: make sure that if the commit
64 // has been manually marked as uninteresting,
65 // all the parent commits are too.
66 if (commit->uninteresting)
67 git_commit__mark_uninteresting(commit);
69 commit->seen = 1;
71 git_commit_list_append(&pool->roots, commit);
72 git_commit_list_append(&pool->iterator, commit);
75 void gitrp_hide(git_revpool *pool, git_commit *commit)
77 git_commit__mark_uninteresting(commit);
78 gitrp_push(pool, commit);
81 void gitrp_prepare_walk(git_revpool *pool)
83 git_commit_node *roots;
85 roots = pool->roots.head;
86 while (roots)
88 git_commit_list_append(&pool->iterator, roots->commit);
89 roots = roots->next;
92 pool->walking = 1;
95 git_commit *gitrp_next(git_revpool *pool)
97 git_commit *next;
99 if (!pool->walking)
100 gitrp_prepare_walk(pool);
102 while ((next = git_commit_list_pop_front(&pool->iterator)) != NULL)
104 git_commit_node *parents;
106 parents = next->parents.head;
107 while (parents)
109 git_commit *parent = parents->commit;
110 parents = parents->next;
112 if (parent->seen)
113 continue;
115 if (parent->parsed == 0)
116 git_commit_parse_existing(parent);
118 git_commit_list_append(&pool->iterator, parent);
121 if (next->uninteresting == 0)
122 return next;
125 // No commits left to iterate
126 gitrp_reset(pool);
127 return NULL;
130 void gitrp_reset(git_revpool *pool)
132 git_commit_list_clear(&pool->iterator, 0);
133 pool->walking = 0;