diff options
author | Etienne Samson <samson.etienne@gmail.com> | 2018-10-25 19:40:19 +0000 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2019-10-03 08:39:49 +0200 |
commit | 1c847a6a70449d18b6fec05fbe83189ba79129ff (patch) | |
tree | cb740dcfdc0474b4e6249a3fe8f2273157291cba | |
parent | 4aa36ff2c0fe2e7b29220737c757ffff99e00059 (diff) | |
download | libgit2-1c847a6a70449d18b6fec05fbe83189ba79129ff.tar.gz |
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.
-rw-r--r-- | src/commit.c | 44 | ||||
-rw-r--r-- | src/commit.h | 6 |
2 files changed, 39 insertions, 11 deletions
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) \ diff --git a/src/commit.h b/src/commit.h index 9137a8fad..318ce5cba 100644 --- a/src/commit.h +++ b/src/commit.h @@ -37,4 +37,10 @@ void git_commit__free(void *commit); int git_commit__parse(void *commit, git_odb_object *obj); int git_commit__parse_raw(void *commit, const char *data, size_t size); +typedef enum { + GIT_COMMIT_PARSE_QUICK = (1 << 0), /**< Only parse parents and committer info */ +} git_commit__parse_flags; + +int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags); + #endif |