log: --show-signature
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>
This commit is contained in:
parent
ba3c69a9ee
commit
0c37f1fce6
44
commit.c
44
commit.c
@ -877,6 +877,50 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
|
|||||||
return 0;
|
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)
|
static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
|
||||||
{
|
{
|
||||||
struct merge_remote_desc *desc;
|
struct merge_remote_desc *desc;
|
||||||
|
2
commit.h
2
commit.h
@ -218,4 +218,6 @@ struct merge_remote_desc {
|
|||||||
*/
|
*/
|
||||||
struct commit *get_merge_parent(const char *name);
|
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 */
|
#endif /* COMMIT_H */
|
||||||
|
39
log-tree.c
39
log-tree.c
@ -8,6 +8,7 @@
|
|||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "gpg-interface.h"
|
||||||
|
|
||||||
struct decoration name_decoration = { "object names" };
|
struct decoration name_decoration = { "object names" };
|
||||||
|
|
||||||
@ -403,6 +404,41 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
|
|||||||
*extra_headers_p = extra_headers;
|
*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)
|
void show_log(struct rev_info *opt)
|
||||||
{
|
{
|
||||||
struct strbuf msgbuf = STRBUF_INIT;
|
struct strbuf msgbuf = STRBUF_INIT;
|
||||||
@ -514,6 +550,9 @@ void show_log(struct rev_info *opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt->show_signature)
|
||||||
|
show_signature(opt, commit);
|
||||||
|
|
||||||
if (!commit->buffer)
|
if (!commit->buffer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -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 = 1;
|
||||||
revs->show_notes_given = 1;
|
revs->show_notes_given = 1;
|
||||||
revs->notes_opt.use_default_notes = 1;
|
revs->notes_opt.use_default_notes = 1;
|
||||||
|
} else if (!strcmp(arg, "--show-signature")) {
|
||||||
|
revs->show_signature = 1;
|
||||||
} else if (!prefixcmp(arg, "--show-notes=") ||
|
} else if (!prefixcmp(arg, "--show-notes=") ||
|
||||||
!prefixcmp(arg, "--notes=")) {
|
!prefixcmp(arg, "--notes=")) {
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
@ -110,6 +110,7 @@ struct rev_info {
|
|||||||
show_merge:1,
|
show_merge:1,
|
||||||
show_notes:1,
|
show_notes:1,
|
||||||
show_notes_given:1,
|
show_notes_given:1,
|
||||||
|
show_signature:1,
|
||||||
pretty_given:1,
|
pretty_given:1,
|
||||||
abbrev_commit:1,
|
abbrev_commit:1,
|
||||||
abbrev_commit_given:1,
|
abbrev_commit_given:1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user