Commit a3f42fe8 by Carlos Martín Nieto

commit: allow retrieving an arbitrary header field

This allows the user to look up fields which we don't parse in libgit2,
and allows them to access gpgsig or mergetag fields if they wish to
check the signature.
parent e96a97f1
......@@ -140,6 +140,9 @@ support for HTTPS connections insead of OpenSSL.
* `git_filter_list_contains` will indicate whether a particular
filter will be run in the given filter list.
* `git_commit_header_field()` has been added, which allows retrieving
the contents of an arbitrary header field.
### API removals
* `git_remote_save()` and `git_remote_clear_refspecs()` have been
......
......@@ -240,6 +240,17 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
unsigned int n);
/**
* Get an arbitrary header field
*
* @param out the buffer to fill
* @param commit the commit to look in
* @param field the header field to return
* @return 0 on succeess, GIT_ENOTFOUND if the field does not exist,
* or an error code
*/
GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
/**
* Create new commit in the repository from a list of `git_object` pointers
*
* The message will **not** be cleaned up automatically. You can do that
......
......@@ -518,3 +518,58 @@ int git_commit_nth_gen_ancestor(
*ancestor = parent;
return 0;
}
int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field)
{
const char *buf = commit->raw_header;
const char *h, *eol;
git_buf_sanitize(out);
while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
h++;
if (git__prefixcmp(h, field)) {
buf = h;
continue;
}
h += strlen(field);
eol = strchr(h, '\n');
if (h[0] != ' ') {
buf = h;
continue;
}
if (!eol)
goto malformed;
h++; /* skip the SP */
git_buf_put(out, h, eol - h);
if (git_buf_oom(out))
goto oom;
/* If the next line starts with SP, it's multi-line, we must continue */
while (eol[1] == ' ') {
git_buf_putc(out, '\n');
h = eol + 2;
eol = strchr(h, '\n');
if (!eol)
goto malformed;
git_buf_put(out, h, eol - h);
}
if (git_buf_oom(out))
goto oom;
return 0;
}
return GIT_ENOTFOUND;
malformed:
giterr_set(GITERR_OBJECT, "malformed header");
return -1;
oom:
giterr_set_oom();
return -1;
}
......@@ -418,3 +418,41 @@ committer Vicent Marti <tanoku@gmail.com> 1273848544 +0200\n\
cl_assert_equal_s(raw_message, git_commit_message_raw(commit));
git_commit__free(commit);
}
void test_commit_parse__arbitrary_field(void)
{
git_commit *commit;
git_buf buf = GIT_BUF_INIT;
const char *gpgsig = "-----BEGIN PGP SIGNATURE-----\n\
Version: GnuPG v1.4.12 (Darwin)\n\
\n\
iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\
o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\
JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\
AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\
SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\
who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\
6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\
cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\
c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\
ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\
7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\
cpxtDQQMGYFpXK/71stq\n\
=ozeK\n\
-----END PGP SIGNATURE-----";
cl_git_pass(parse_commit(&commit, passing_commit_cases[4]));
cl_git_pass(git_commit_header_field(&buf, commit, "parent"));
cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr);
git_buf_clear(&buf);
cl_git_pass(git_commit_header_field(&buf, commit, "gpgsig"));
cl_assert_equal_s(gpgsig, buf.ptr);
cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "awesomeness"));
cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "par"));
git_buf_free(&buf);
git_commit__free(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