From 1c847a6a70449d18b6fec05fbe83189ba79129ff Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 25 Oct 2018 19:40:19 +0000 Subject: commit: generic parse mechanism This allows us to pick which data from a commit we're interested in. This will be used by the revwalk code, which is only interested in parents' and committer data. --- src/commit.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'src/commit.c') diff --git a/src/commit.c b/src/commit.c index 513fdccaf..483bdedb7 100644 --- a/src/commit.c +++ b/src/commit.c @@ -20,6 +20,7 @@ #include "message.h" #include "refs.h" #include "object.h" +#include "array.h" #include "oidarray.h" void git_commit__free(void *_commit) @@ -383,15 +384,16 @@ int git_commit_amend( return error; } -int git_commit__parse_raw(void *_commit, const char *data, size_t size) +static int commit_parse(git_commit *commit, const char *data, size_t size, unsigned int flags) { - git_commit *commit = _commit; const char *buffer_start = data, *buffer; const char *buffer_end = buffer_start + size; git_oid parent_id; size_t header_len; git_signature dummy_sig; + assert(commit && data); + buffer = buffer_start; /* Allocate for one, which will allow not to realloc 90% of the time */ @@ -399,8 +401,15 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size) GIT_ERROR_CHECK_ARRAY(commit->parent_ids); /* The tree is always the first field */ - if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) - goto bad_buffer; + if (!(flags & GIT_COMMIT_PARSE_QUICK)) { + if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) + goto bad_buffer; + } else { + size_t tree_len = strlen("tree ") + GIT_OID_HEXSZ + 1; + if (buffer + tree_len > buffer_end) + goto bad_buffer; + buffer += tree_len; + } /* * TODO: commit grafts! @@ -413,11 +422,13 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size) git_oid_cpy(new_id, &parent_id); } - commit->author = git__malloc(sizeof(git_signature)); - GIT_ERROR_CHECK_ALLOC(commit->author); + if (!(flags & GIT_COMMIT_PARSE_QUICK)) { + commit->author = git__malloc(sizeof(git_signature)); + GIT_ERROR_CHECK_ALLOC(commit->author); - if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0) - return -1; + if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0) + return -1; + } /* Some tools create multiple author fields, ignore the extra ones */ while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) { @@ -435,6 +446,9 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size) if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0) return -1; + if (flags & GIT_COMMIT_PARSE_QUICK) + return 0; + /* Parse add'l header entries */ while (buffer < buffer_end) { const char *eoln = buffer; @@ -477,11 +491,19 @@ bad_buffer: return -1; } +int git_commit__parse_raw(void *commit, const char *data, size_t size) +{ + return commit_parse(commit, data, size, 0); +} + +int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags) +{ + return commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), flags); +} + int git_commit__parse(void *_commit, git_odb_object *odb_obj) { - return git_commit__parse_raw(_commit, - git_odb_object_data(odb_obj), - git_odb_object_size(odb_obj)); + return git_commit__parse_ext(_commit, odb_obj, 0); } #define GIT_COMMIT_GETTER(_rvalue, _name, _return) \ -- cgit v1.2.1