mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-06 18:03:32 +00:00
commit: add function to attach a signature to a commit
In combination with the function which creates a commit into a buffer, this allows us to more easily create signed commits.
This commit is contained in:
parent
2ba9a0ddac
commit
02d61a3b66
@ -440,6 +440,27 @@ GIT_EXTERN(int) git_commit_create_buffer(
|
||||
size_t parent_count,
|
||||
const git_commit *parents[]);
|
||||
|
||||
/**
|
||||
* Create a commit object from the given buffer and signature
|
||||
*
|
||||
* Given the unsigned commit object's contents, its signature and the
|
||||
* header field in which to store the signature, attach the signature
|
||||
* to the commit and write it into the given repository.
|
||||
*
|
||||
* @param out the resulting commit id
|
||||
* @param commit_content the content of the unsigned commit object
|
||||
* @param signature the signature to add to the commit
|
||||
* @param signature_field which header field should contain this
|
||||
* signature. Leave `NULL` for the default of "gpgsig"
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_create_with_signature(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const char *commit_content,
|
||||
const char *signature,
|
||||
const char *signature_field);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
64
src/commit.c
64
src/commit.c
@ -820,3 +820,67 @@ int git_commit_create_buffer(git_buf *out,
|
||||
git_array_clear(parents_arr);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append to 'out' properly marking continuations when there's a newline in 'content'
|
||||
*/
|
||||
static void format_header_field(git_buf *out, const char *field, const char *content)
|
||||
{
|
||||
const char *lf;
|
||||
|
||||
assert(out && field && content);
|
||||
|
||||
git_buf_puts(out, field);
|
||||
git_buf_putc(out, ' ');
|
||||
|
||||
while ((lf = strchr(content, '\n')) != NULL) {
|
||||
git_buf_put(out, content, lf - content);
|
||||
git_buf_puts(out, "\n ");
|
||||
content = lf + 1;
|
||||
}
|
||||
|
||||
git_buf_puts(out, content);
|
||||
git_buf_putc(out, '\n');
|
||||
}
|
||||
|
||||
int git_commit_create_with_signature(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const char *commit_content,
|
||||
const char *signature,
|
||||
const char *signature_field)
|
||||
{
|
||||
git_odb *odb;
|
||||
int error = 0;
|
||||
const char *field;
|
||||
const char *header_end;
|
||||
git_buf commit = GIT_BUF_INIT;
|
||||
|
||||
/* We start by identifying the end of the commit header */
|
||||
header_end = strstr(commit_content, "\n\n");
|
||||
if (!header_end) {
|
||||
giterr_set(GITERR_INVALID, "malformed commit contents");
|
||||
return -1;
|
||||
}
|
||||
|
||||
field = signature_field ? signature_field : "gpgsig";
|
||||
|
||||
/* The header ends after the first LF */
|
||||
header_end++;
|
||||
git_buf_put(&commit, commit_content, header_end - commit_content);
|
||||
format_header_field(&commit, field, signature);
|
||||
git_buf_puts(&commit, header_end);
|
||||
|
||||
if (git_buf_oom(&commit))
|
||||
return -1;
|
||||
|
||||
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_odb_write(out, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&commit);
|
||||
return error;
|
||||
}
|
||||
|
@ -298,3 +298,103 @@ void test_commit_write__can_validate_objects(void)
|
||||
git_oid_fromstr(&parent_id, tree_id_str);
|
||||
cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
|
||||
}
|
||||
|
||||
void test_commit_write__attach_singleline_signature(void)
|
||||
{
|
||||
const char *sig = "magic word: pretty please";
|
||||
|
||||
const char *data = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
|
||||
parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
|
||||
author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
\n\
|
||||
a simple commit which works\n";
|
||||
|
||||
const char *complete = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
|
||||
parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
|
||||
author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
magicsig magic word: pretty please\n\
|
||||
\n\
|
||||
a simple commit which works\n";
|
||||
|
||||
git_oid id;
|
||||
git_odb *odb;
|
||||
git_odb_object *obj;
|
||||
|
||||
cl_git_pass(git_commit_create_with_signature(&id, g_repo, data, sig, "magicsig"));
|
||||
|
||||
cl_git_pass(git_repository_odb(&odb, g_repo));
|
||||
cl_git_pass(git_odb_read(&obj, odb, &id));
|
||||
cl_assert_equal_s(complete, git_odb_object_data(obj));
|
||||
|
||||
git_odb_object_free(obj);
|
||||
git_odb_free(odb);
|
||||
}
|
||||
|
||||
void test_commit_write__attach_multiline_signature(void)
|
||||
{
|
||||
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-----";
|
||||
|
||||
const char *data = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
|
||||
parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
|
||||
author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
\n\
|
||||
a simple commit which works\n";
|
||||
|
||||
const char *complete = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
|
||||
parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
|
||||
author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
|
||||
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-----\n\
|
||||
\n\
|
||||
a simple commit which works\n";
|
||||
|
||||
git_oid one, two;
|
||||
git_odb *odb;
|
||||
git_odb_object *obj;
|
||||
|
||||
cl_git_pass(git_commit_create_with_signature(&one, g_repo, data, gpgsig, "gpgsig"));
|
||||
cl_git_pass(git_commit_create_with_signature(&two, g_repo, data, gpgsig, NULL));
|
||||
|
||||
cl_assert(!git_oid_cmp(&one, &two));
|
||||
cl_git_pass(git_repository_odb(&odb, g_repo));
|
||||
cl_git_pass(git_odb_read(&obj, odb, &one));
|
||||
cl_assert_equal_s(complete, git_odb_object_data(obj));
|
||||
|
||||
git_odb_object_free(obj);
|
||||
git_odb_free(odb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user