Commit 1c847a6a by Etienne Samson Committed by Patrick Steinhardt

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.
parent 4aa36ff2
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "message.h" #include "message.h"
#include "refs.h" #include "refs.h"
#include "object.h" #include "object.h"
#include "array.h"
#include "oidarray.h" #include "oidarray.h"
void git_commit__free(void *_commit) void git_commit__free(void *_commit)
...@@ -383,15 +384,16 @@ int git_commit_amend( ...@@ -383,15 +384,16 @@ int git_commit_amend(
return error; 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_start = data, *buffer;
const char *buffer_end = buffer_start + size; const char *buffer_end = buffer_start + size;
git_oid parent_id; git_oid parent_id;
size_t header_len; size_t header_len;
git_signature dummy_sig; git_signature dummy_sig;
assert(commit && data);
buffer = buffer_start; buffer = buffer_start;
/* Allocate for one, which will allow not to realloc 90% of the time */ /* 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) ...@@ -399,8 +401,15 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
GIT_ERROR_CHECK_ARRAY(commit->parent_ids); GIT_ERROR_CHECK_ARRAY(commit->parent_ids);
/* The tree is always the first field */ /* The tree is always the first field */
if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) if (!(flags & GIT_COMMIT_PARSE_QUICK)) {
goto bad_buffer; 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! * TODO: commit grafts!
...@@ -413,11 +422,13 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size) ...@@ -413,11 +422,13 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
git_oid_cpy(new_id, &parent_id); git_oid_cpy(new_id, &parent_id);
} }
commit->author = git__malloc(sizeof(git_signature)); if (!(flags & GIT_COMMIT_PARSE_QUICK)) {
GIT_ERROR_CHECK_ALLOC(commit->author); 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) if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
return -1; return -1;
}
/* Some tools create multiple author fields, ignore the extra ones */ /* Some tools create multiple author fields, ignore the extra ones */
while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) { 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) ...@@ -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) if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
return -1; return -1;
if (flags & GIT_COMMIT_PARSE_QUICK)
return 0;
/* Parse add'l header entries */ /* Parse add'l header entries */
while (buffer < buffer_end) { while (buffer < buffer_end) {
const char *eoln = buffer; const char *eoln = buffer;
...@@ -477,11 +491,19 @@ bad_buffer: ...@@ -477,11 +491,19 @@ bad_buffer:
return -1; 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) int git_commit__parse(void *_commit, git_odb_object *odb_obj)
{ {
return git_commit__parse_raw(_commit, return git_commit__parse_ext(_commit, odb_obj, 0);
git_odb_object_data(odb_obj),
git_odb_object_size(odb_obj));
} }
#define GIT_COMMIT_GETTER(_rvalue, _name, _return) \ #define GIT_COMMIT_GETTER(_rvalue, _name, _return) \
......
...@@ -37,4 +37,10 @@ void git_commit__free(void *commit); ...@@ -37,4 +37,10 @@ void git_commit__free(void *commit);
int git_commit__parse(void *commit, git_odb_object *obj); int git_commit__parse(void *commit, git_odb_object *obj);
int git_commit__parse_raw(void *commit, const char *data, size_t size); 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 #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment