Commit f094f905 by Russell Belfer Committed by Vicent Marti

Add raw header access to commit API

parent 8ba0ff69
...@@ -130,6 +130,14 @@ GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit) ...@@ -130,6 +130,14 @@ GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit)
GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit); GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
/** /**
* Get the full raw text of the commit header.
*
* @param commit a previously loaded commit
* @return the header text of the commit
*/
GIT_EXTERN(const char *) git_commit_raw_header(const git_commit *commit);
/**
* Get the tree pointed to by a commit. * Get the tree pointed to by a commit.
* *
* @param tree_out pointer where to store the tree object * @param tree_out pointer where to store the tree object
......
...@@ -41,6 +41,7 @@ void git_commit__free(void *_commit) ...@@ -41,6 +41,7 @@ void git_commit__free(void *_commit)
git_signature_free(commit->author); git_signature_free(commit->author);
git_signature_free(commit->committer); git_signature_free(commit->committer);
git__free(commit->raw_header);
git__free(commit->message); git__free(commit->message);
git__free(commit->message_encoding); git__free(commit->message_encoding);
git__free(commit); git__free(commit);
...@@ -171,11 +172,33 @@ int git_commit_create( ...@@ -171,11 +172,33 @@ int git_commit_create(
int git_commit__parse(void *_commit, git_odb_object *odb_obj) int git_commit__parse(void *_commit, git_odb_object *odb_obj)
{ {
git_commit *commit = _commit; git_commit *commit = _commit;
const char *buffer = git_odb_object_data(odb_obj); const char *buffer_start = git_odb_object_data(odb_obj), *buffer;
const char *buffer_end = buffer + git_odb_object_size(odb_obj); const char *buffer_end = buffer_start + git_odb_object_size(odb_obj);
git_oid parent_id; git_oid parent_id;
size_t parent_count = 0, header_len;
if (git_vector_init(&commit->parent_ids, 4, NULL) < 0) /* find end-of-header (counting parents as we go) */
for (buffer = buffer_start; buffer < buffer_end; ++buffer) {
if (!strncmp("\n\n", buffer, 2)) {
++buffer;
break;
}
if (!strncmp("\nparent ", buffer, strlen("\nparent ")))
++parent_count;
}
header_len = buffer - buffer_start;
commit->raw_header = git__strndup(buffer_start, header_len);
GITERR_CHECK_ALLOC(commit->raw_header);
/* point "buffer" to header data */
buffer = commit->raw_header;
buffer_end = commit->raw_header + header_len;
if (parent_count < 1)
parent_count = 1;
if (git_vector_init(&commit->parent_ids, parent_count, NULL) < 0)
return -1; return -1;
if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
...@@ -208,8 +231,8 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) ...@@ -208,8 +231,8 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
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;
/* Parse add'l header entries until blank line found */ /* Parse add'l header entries */
while (buffer < buffer_end && *buffer != '\n') { while (buffer < buffer_end) {
const char *eoln = buffer; const char *eoln = buffer;
while (eoln < buffer_end && *eoln != '\n') while (eoln < buffer_end && *eoln != '\n')
++eoln; ++eoln;
...@@ -223,15 +246,18 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) ...@@ -223,15 +246,18 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
if (eoln < buffer_end && *eoln == '\n') if (eoln < buffer_end && *eoln == '\n')
++eoln; ++eoln;
buffer = eoln; buffer = eoln;
} }
/* buffer is now at the end of the header, double-check and move forward into the message */ /* point "buffer" to data after header */
if (buffer < buffer_end && *buffer == '\n') buffer = git_odb_object_data(odb_obj);
buffer++; buffer_end = buffer + git_odb_object_size(odb_obj);
buffer += header_len;
if (*buffer == '\n')
++buffer;
/* parse commit message */ /* extract commit message */
if (buffer <= buffer_end) { if (buffer <= buffer_end) {
commit->message = git__strndup(buffer, buffer_end - buffer); commit->message = git__strndup(buffer, buffer_end - buffer);
GITERR_CHECK_ALLOC(commit->message); GITERR_CHECK_ALLOC(commit->message);
...@@ -255,6 +281,7 @@ GIT_COMMIT_GETTER(const git_signature *, author, commit->author) ...@@ -255,6 +281,7 @@ GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer) GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
GIT_COMMIT_GETTER(const char *, message, commit->message) GIT_COMMIT_GETTER(const char *, message, commit->message)
GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding) GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding)
GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header)
GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time) GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset) GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)commit->parent_ids.length) GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)commit->parent_ids.length)
......
...@@ -25,6 +25,7 @@ struct git_commit { ...@@ -25,6 +25,7 @@ struct git_commit {
char *message_encoding; char *message_encoding;
char *message; char *message;
char *raw_header;
}; };
void git_commit__free(void *commit); void git_commit__free(void *commit);
......
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