diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2016-03-10 10:53:20 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2016-03-15 12:55:03 +0100 |
commit | 02d61a3b66a6e5f5bc0154d780daaf5f7b71ccd9 (patch) | |
tree | 1dadcb0464c89bf1863a83c826931f93c655e5da /src/commit.c | |
parent | 2ba9a0ddacd315dafb54990ff2bfa204e6924016 (diff) | |
download | libgit2-cmn/commit-with-signature.tar.gz |
commit: add function to attach a signature to a commitcmn/commit-with-signature
In combination with the function which creates a commit into a buffer,
this allows us to more easily create signed commits.
Diffstat (limited to 'src/commit.c')
-rw-r--r-- | src/commit.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/commit.c b/src/commit.c index 9d675ac97..f6b2d6517 100644 --- a/src/commit.c +++ b/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; +} |