summaryrefslogtreecommitdiff
path: root/src/commit.c
diff options
context:
space:
mode:
authorEtienne Samson <samson.etienne@gmail.com>2018-10-25 19:40:19 +0000
committerPatrick Steinhardt <ps@pks.im>2019-10-03 08:39:49 +0200
commit1c847a6a70449d18b6fec05fbe83189ba79129ff (patch)
treecb740dcfdc0474b4e6249a3fe8f2273157291cba /src/commit.c
parent4aa36ff2c0fe2e7b29220737c757ffff99e00059 (diff)
downloadlibgit2-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.
Diffstat (limited to 'src/commit.c')
-rw-r--r--src/commit.c44
1 files changed, 33 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) \