diff options
Diffstat (limited to 'src/commit_list.c')
-rw-r--r-- | src/commit_list.c | 100 |
1 files changed, 23 insertions, 77 deletions
diff --git a/src/commit_list.c b/src/commit_list.c index 5496dca44..209655434 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; |