summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ba3c69a)
raw | patch | inline | side by side (parent: ba3c69a)
author | Junio C Hamano <gitster@pobox.com> | |
Tue, 18 Oct 2011 22:53:23 +0000 (15:53 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sun, 13 Nov 2011 06:27:38 +0000 (22:27 -0800) |
This teaches the "log" family of commands to pass the GPG signature in the
commit objects to "gpg --verify" via the verify_signed_buffer() interface
used to verify signed tag objects. E.g.
$ git show --show-signature -s HEAD
shows GPG output in the header part of the output.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit objects to "gpg --verify" via the verify_signed_buffer() interface
used to verify signed tag objects. E.g.
$ git show --show-signature -s HEAD
shows GPG output in the header part of the output.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit.c | patch | blob | history | |
commit.h | patch | blob | history | |
log-tree.c | patch | blob | history | |
revision.c | patch | blob | history | |
revision.h | patch | blob | history |
diff --git a/commit.c b/commit.c
index f00076e91f859d3efcc7cd9f80022c5ef5550f0f..27c7226abbfd95251bc2831a8a6447a8e35f264b 100644 (file)
--- a/commit.c
+++ b/commit.c
return 0;
}
+int parse_signed_commit(const unsigned char *sha1,
+ struct strbuf *payload, struct strbuf *signature)
+{
+ unsigned long size;
+ enum object_type type;
+ char *buffer = read_sha1_file(sha1, &type, &size);
+ int in_signature, saw_signature = -1;
+ char *line, *tail;
+
+ if (!buffer || type != OBJ_COMMIT)
+ goto cleanup;
+
+ line = buffer;
+ tail = buffer + size;
+ in_signature = 0;
+ saw_signature = 0;
+ while (line < tail) {
+ const char *sig = NULL;
+ char *next = memchr(line, '\n', tail - line);
+
+ next = next ? next + 1 : tail;
+ if (in_signature && line[0] == ' ')
+ sig = line + 1;
+ else if (!prefixcmp(line, gpg_sig_header) &&
+ line[gpg_sig_header_len] == ' ')
+ sig = line + gpg_sig_header_len + 1;
+ if (sig) {
+ strbuf_add(signature, sig, next - sig);
+ saw_signature = 1;
+ in_signature = 1;
+ } else {
+ if (*line == '\n')
+ /* dump the whole remainder of the buffer */
+ next = tail;
+ strbuf_add(payload, line, next - line);
+ in_signature = 0;
+ }
+ line = next;
+ }
+ cleanup:
+ free(buffer);
+ return saw_signature;
+}
+
static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
{
struct merge_remote_desc *desc;
diff --git a/commit.h b/commit.h
index d2c3e650b18f4ec63be9c49a7c9d30f7e1eb99bb..61076486df7de2502344039b62ad60f534807cf6 100644 (file)
--- a/commit.h
+++ b/commit.h
*/
struct commit *get_merge_parent(const char *name);
+extern int parse_signed_commit(const unsigned char *sha1,
+ struct strbuf *message, struct strbuf *signature);
#endif /* COMMIT_H */
diff --git a/log-tree.c b/log-tree.c
index e7694a3a4ca2e6de7fe8f3b5458eb2b65591373a..142ba5142782cde77477eeda6bc788d5c80bd3a3 100644 (file)
--- a/log-tree.c
+++ b/log-tree.c
#include "refs.h"
#include "string-list.h"
#include "color.h"
+#include "gpg-interface.h"
struct decoration name_decoration = { "object names" };
*extra_headers_p = extra_headers;
}
+static void show_signature(struct rev_info *opt, struct commit *commit)
+{
+ struct strbuf payload = STRBUF_INIT;
+ struct strbuf signature = STRBUF_INIT;
+ struct strbuf gpg_output = STRBUF_INIT;
+ int status;
+ const char *color, *reset, *bol, *eol;
+
+ if (parse_signed_commit(commit->object.sha1, &payload, &signature) <= 0)
+ goto out;
+
+ status = verify_signed_buffer(payload.buf, payload.len,
+ signature.buf, signature.len,
+ &gpg_output);
+ if (status && !gpg_output.len)
+ strbuf_addstr(&gpg_output, "No signature\n");
+
+ color = diff_get_color_opt(&opt->diffopt,
+ status ? DIFF_WHITESPACE : DIFF_FRAGINFO);
+ reset = diff_get_color_opt(&opt->diffopt, DIFF_RESET);
+
+ bol = gpg_output.buf;
+ while (*bol) {
+ eol = strchrnul(bol, '\n');
+ printf("%s%.*s%s%s", color, (int)(eol - bol), bol, reset,
+ *eol ? "\n" : "");
+ bol = (*eol) ? (eol + 1) : eol;
+ }
+
+ out:
+ strbuf_release(&gpg_output);
+ strbuf_release(&payload);
+ strbuf_release(&signature);
+}
+
void show_log(struct rev_info *opt)
{
struct strbuf msgbuf = STRBUF_INIT;
}
}
+ if (opt->show_signature)
+ show_signature(opt, commit);
+
if (!commit->buffer)
return;
diff --git a/revision.c b/revision.c
index 8764dde381111cfc9c8ea7eb3856223de9786ec9..064e35108478431e82ec08464203fe119f24c1d6 100644 (file)
--- a/revision.c
+++ b/revision.c
@@ -1469,6 +1469,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->show_notes = 1;
revs->show_notes_given = 1;
revs->notes_opt.use_default_notes = 1;
+ } else if (!strcmp(arg, "--show-signature")) {
+ revs->show_signature = 1;
} else if (!prefixcmp(arg, "--show-notes=") ||
!prefixcmp(arg, "--notes=")) {
struct strbuf buf = STRBUF_INIT;
diff --git a/revision.h b/revision.h
index 6aa53d1aa708918e4bbbebb042e0bf75c1629b05..b8e9223954a5d66e01bd1eb342a936495aa67ad1 100644 (file)
--- a/revision.h
+++ b/revision.h
show_merge:1,
show_notes:1,
show_notes_given:1,
+ show_signature:1,
pretty_given:1,
abbrev_commit:1,
abbrev_commit_given:1,