Split git_commit_lookup into separate functions. git_commit_lookup() now creates commit references without loading them from the ODB. git_commit_parse() creates a commit reference, loads it and parses it from the ODB. Signed-off-by: Vicent Marti <tanoku@gmail.com> Signed-off-by: Andreas Ericsson <ae@op5.se>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
diff --git a/src/commit.c b/src/commit.c
index 8844825..fa33b52 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -51,41 +51,71 @@ void git_commit_mark_uninteresting(git_commit *commit)
}
}
-git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
+git_commit *git_commit_parse(git_revpool *pool, const git_oid *id)
{
- git_obj commit_obj;
git_commit *commit = NULL;
- if (pool == NULL || pool->db == NULL)
+ if ((commit = git_commit_lookup(pool, id)) == NULL)
return NULL;
- /*
- * TODO: check if the commit is already cached in the
- * revpool instead of loading it from the odb
- */
+ if (git_commit_parse_existing(commit) < 0)
+ goto error_cleanup;
- if (git_odb_read(&commit_obj, pool->db, id) < 0)
- return NULL;
+ return commit;
+
+error_cleanup:
+ free(commit);
+ return NULL;
+}
+
+int git_commit_parse_existing(git_commit *commit)
+{
+ git_obj commit_obj;
+
+ if (commit->parsed)
+ return 0;
+
+ if (commit->pool == NULL || commit->pool->db == NULL)
+ return -1;
+
+ if (git_odb_read(&commit_obj, commit->pool->db, &commit->id) < 0)
+ return -1;
if (commit_obj.type != GIT_OBJ_COMMIT)
goto error_cleanup;
+ if (git_commit__parse_buffer(commit, commit_obj.data, commit_obj.len) < 0)
+ goto error_cleanup;
+
+ git_obj_close(&commit_obj);
+
+ return 0;
+
+error_cleanup:
+ git_obj_close(&commit_obj);
+ return -1;
+}
+
+git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
+{
+ git_commit *commit = NULL;
+
+ if (pool == NULL || pool->db == NULL)
+ return NULL;
+
commit = git__malloc(sizeof(git_commit));
+
+ if (commit == NULL)
+ return NULL;
+
memset(commit, 0x0, sizeof(git_commit));
git_oid_cpy(&commit->id, id);
commit->pool = pool;
- if (git_commit__parse_buffer(commit, commit_obj.data, commit_obj.len) < 0)
- goto error_cleanup;
+ git_commit_list_insert(&pool->commits, commit);
return commit;
-
-error_cleanup:
- git_obj_close(&commit_obj);
- free(commit);
-
- return NULL;
}
int git_commit__parse_time(time_t *commit_time, char *buffer, const char *buffer_end)
@@ -111,8 +141,8 @@ int git_commit__parse_time(time_t *commit_time, char *buffer, const char *buffer
int git_commit__parse_oid(git_oid *oid, char **buffer_out, const char *buffer_end, const char *header)
{
- size_t sha_len = GIT_OID_HEXSZ;
- size_t header_len = strlen(header);
+ const size_t sha_len = GIT_OID_HEXSZ;
+ const size_t header_len = strlen(header);
char *buffer = *buffer_out;
diff --git a/src/commit.h b/src/commit.h
index 7ab2d54..3a6b706 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -30,6 +30,8 @@ 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);
+int git_commit_parse_existing(git_commit *commit);
+
void git_commit_list_insert(git_commit_list **list, git_commit *commit);
#endif
diff --git a/src/git/commit.h b/src/git/commit.h
index ea59a21..1a57ba7 100644
--- a/src/git/commit.h
+++ b/src/git/commit.h
@@ -17,7 +17,17 @@ GIT_BEGIN_DECL
typedef struct git_commit git_commit;
/**
- * Lookup a commit from a revision pool, and parse it if needed.
+ * Locate a reference to a commit without loading it.
+ * @param pool the pool to use when locating the commit.
+ * @param id identity of the commit to locate. If the object is
+ * an annotated tag it will be peeled back to the commit.
+ * @return the commit; NULL if the commit could not be created
+ */
+GIT_EXTERN(git_commit *) git_commit_lookup(git_revpool *pool, const git_oid *id);
+
+/**
+ * Locate a reference to a commit, and try to load and parse it it from
+ * the commit cache or the object database.
* @param pool the pool to use when parsing/caching the commit.
* @param id identity of the commit to locate. If the object is
* an annotated tag it will be peeled back to the commit.
@@ -25,7 +35,7 @@ typedef struct git_commit git_commit;
* pool's git_odb, or if the commit is present but is
* too malformed to be parsed successfully.
*/
-GIT_EXTERN(git_commit *) git_commit_lookup(git_revpool *pool, const git_oid *id);
+GIT_EXTERN(git_commit *) git_commit_parse(git_revpool *pool, const git_oid *id);
/**
* Get the id of a commit.
diff --git a/src/revwalk.c b/src/revwalk.c
index 96f3444..fe6f9f2 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -41,31 +41,42 @@ git_revpool *gitrp_alloc(git_odb *db)
void gitrp_free(git_revpool *walk)
{
+ git_commit_list *list;
+
+ list = walk->commits;
+ while (list)
+ {
+ free(list->commit);
+ list = list->next;
+ }
+
free(walk);
}
void gitrp_push(git_revpool *pool, git_commit *commit)
{
+ if (commit->pool != pool)
+ return;
+
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;
+ {
+ if (git_commit_parse_existing(commit) < 0)
+ return;
+ }
commit->flags |= GIT_COMMIT_SEEN;
- git_commit_list_insert(&pool->commits, commit);
+ git_commit_list_insert(&pool->roots, commit);
}
void gitrp_prepare_walk(git_revpool *pool)
{
// TODO: sort commit list based on walk ordering
- pool->iterator = pool->commits;
+ pool->iterator = pool->roots;
pool->walking = 1;
}
diff --git a/src/revwalk.h b/src/revwalk.h
index edf57b4..34ff337 100644
--- a/src/revwalk.h
+++ b/src/revwalk.h
@@ -8,6 +8,7 @@ struct git_revpool {
git_odb *db;
git_commit_list *iterator;
git_commit_list *commits;
+ git_commit_list *roots;
unsigned walking:1,
topological_sort:1;