commit_list: unify commit information parsing
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
diff --git a/src/commit_list.c b/src/commit_list.c
index 5496dca..2096554 100644
--- a/src/commit_list.c
+++ b/src/commit_list.c
@@ -10,6 +10,7 @@
#include "revwalk.h"
#include "pool.h"
#include "odb.h"
+#include "commit.h"
int git_commit_list_time_cmp(const void *a, const void *b)
{
@@ -55,17 +56,6 @@ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk)
return (git_commit_list_node *)git_pool_mallocz(&walk->commit_pool, 1);
}
-static int commit_error(git_commit_list_node *commit, const char *msg)
-{
- char commit_oid[GIT_OID_HEXSZ + 1];
- git_oid_fmt(commit_oid, &commit->oid);
- commit_oid[GIT_OID_HEXSZ] = '\0';
-
- git_error_set(GIT_ERROR_ODB, "failed to parse commit %s - %s", commit_oid, msg);
-
- return -1;
-}
-
static git_commit_list_node **alloc_parents(
git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
{
@@ -107,77 +97,36 @@ git_commit_list_node *git_commit_list_pop(git_commit_list **stack)
static int commit_quick_parse(
git_revwalk *walk,
- git_commit_list_node *commit,
- const uint8_t *buffer,
- size_t buffer_len)
+ git_commit_list_node *node,
+ git_odb_object *obj)
{
- const size_t parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1;
- const uint8_t *buffer_end = buffer + buffer_len;
- const uint8_t *parents_start, *committer_start;
- int i, parents = 0;
- int64_t commit_time;
-
- buffer += strlen("tree ") + GIT_OID_HEXSZ + 1;
-
- parents_start = buffer;
- while (buffer + parent_len < buffer_end && memcmp(buffer, "parent ", strlen("parent ")) == 0) {
- parents++;
- buffer += parent_len;
- }
-
- commit->parents = alloc_parents(walk, commit, parents);
- GIT_ERROR_CHECK_ALLOC(commit->parents);
-
- buffer = parents_start;
- for (i = 0; i < parents; ++i) {
- git_oid oid;
-
- if (git_oid_fromstr(&oid, (const char *)buffer + strlen("parent ")) < 0)
- return -1;
+ git_oid *parent_oid;
+ git_commit *commit;
+ int error;
+ size_t i;
- commit->parents[i] = git_revwalk__commit_lookup(walk, &oid);
- if (commit->parents[i] == NULL)
- return -1;
+ commit = git__calloc(1, sizeof(*commit));
+ GIT_ERROR_CHECK_ALLOC(commit);
+ commit->object.repo = walk->repo;
- buffer += parent_len;
+ if ((error = git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK)) < 0) {
+ git__free(commit);
+ return error;
}
- commit->out_degree = (unsigned short)parents;
-
- if ((committer_start = buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
- return commit_error(commit, "object is corrupted");
-
- buffer++;
-
- if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
- return commit_error(commit, "object is corrupted");
-
- /* Skip trailing spaces */
- while (buffer > committer_start && git__isspace(*buffer))
- buffer--;
+ node->time = commit->committer->when.time;
+ node->out_degree = git_array_size(commit->parent_ids);
+ node->parents = alloc_parents(walk, node, node->out_degree);
+ GIT_ERROR_CHECK_ALLOC(node->parents);
- /* Seek for the beginning of the pack of digits */
- while (buffer > committer_start && git__isdigit(*buffer))
- buffer--;
-
- /* Skip potential timezone offset */
- if ((buffer > committer_start) && (*buffer == '+' || *buffer == '-')) {
- buffer--;
-
- while (buffer > committer_start && git__isspace(*buffer))
- buffer--;
-
- while (buffer > committer_start && git__isdigit(*buffer))
- buffer--;
+ git_array_foreach(commit->parent_ids, i, parent_oid) {
+ node->parents[i] = git_revwalk__commit_lookup(walk, parent_oid);
}
- if ((buffer == committer_start) ||
- (git__strntol64(&commit_time, (char *)(buffer + 1),
- buffer_end - buffer + 1, NULL, 10) < 0))
- return commit_error(commit, "cannot parse commit time");
+ git_commit__free(commit);
+
+ node->parsed = 1;
- commit->time = commit_time;
- commit->parsed = 1;
return 0;
}
@@ -196,10 +145,7 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
git_error_set(GIT_ERROR_INVALID, "object is no commit object");
error = -1;
} else
- error = commit_quick_parse(
- walk, commit,
- (const uint8_t *)git_odb_object_data(obj),
- git_odb_object_size(obj));
+ error = commit_quick_parse(walk, commit, obj);
git_odb_object_free(obj);
return error;