From: Junio C Hamano Date: Fri, 2 Nov 2018 15:53:58 +0000 (+0900) Subject: Merge branch 'mg/gpg-fingerprint' X-Git-Tag: v2.20.0-rc0~78 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/11cc180fa5c4428faa64acf3507fa96d9636ad34?ds=inline;hp=-c Merge branch 'mg/gpg-fingerprint' New "--pretty=format:" placeholders %GF and %GP that show the GPG key fingerprints have been invented. * mg/gpg-fingerprint: gpg-interface.c: obtain primary key fingerprint as well gpg-interface.c: support getting key fingerprint via %GF format gpg-interface.c: use flags to determine key/signer info presence --- 11cc180fa5c4428faa64acf3507fa96d9636ad34 diff --combined gpg-interface.c index d72a43b774,bea1aa2b5a..8ed274533f --- a/gpg-interface.c +++ b/gpg-interface.c @@@ -73,31 -73,43 +73,43 @@@ void signature_check_clear(struct signa FREE_AND_NULL(sigc->gpg_status); FREE_AND_NULL(sigc->signer); FREE_AND_NULL(sigc->key); + FREE_AND_NULL(sigc->fingerprint); + FREE_AND_NULL(sigc->primary_key_fingerprint); } /* An exclusive status -- only one of them can appear in output */ #define GPG_STATUS_EXCLUSIVE (1<<0) + /* The status includes key identifier */ + #define GPG_STATUS_KEYID (1<<1) + /* The status includes user identifier */ + #define GPG_STATUS_UID (1<<2) + /* The status includes key fingerprints */ + #define GPG_STATUS_FINGERPRINT (1<<3) + + /* Short-hand for standard exclusive *SIG status with keyid & UID */ + #define GPG_STATUS_STDSIG (GPG_STATUS_EXCLUSIVE|GPG_STATUS_KEYID|GPG_STATUS_UID) static struct { char result; const char *check; unsigned int flags; } sigcheck_gpg_status[] = { - { 'G', "GOODSIG ", GPG_STATUS_EXCLUSIVE }, - { 'B', "BADSIG ", GPG_STATUS_EXCLUSIVE }, + { 'G', "GOODSIG ", GPG_STATUS_STDSIG }, + { 'B', "BADSIG ", GPG_STATUS_STDSIG }, { 'U', "TRUST_NEVER", 0 }, { 'U', "TRUST_UNDEFINED", 0 }, - { 'E', "ERRSIG ", GPG_STATUS_EXCLUSIVE }, - { 'X', "EXPSIG ", GPG_STATUS_EXCLUSIVE }, - { 'Y', "EXPKEYSIG ", GPG_STATUS_EXCLUSIVE }, - { 'R', "REVKEYSIG ", GPG_STATUS_EXCLUSIVE }, + { 'E', "ERRSIG ", GPG_STATUS_EXCLUSIVE|GPG_STATUS_KEYID }, + { 'X', "EXPSIG ", GPG_STATUS_STDSIG }, + { 'Y', "EXPKEYSIG ", GPG_STATUS_STDSIG }, + { 'R', "REVKEYSIG ", GPG_STATUS_STDSIG }, + { 0, "VALIDSIG ", GPG_STATUS_FINGERPRINT }, }; static void parse_gpg_output(struct signature_check *sigc) { const char *buf = sigc->gpg_status; const char *line, *next; - int i; + int i, j; int seen_exclusive_status = 0; /* Iterate over all lines */ @@@ -112,24 -124,43 +124,43 @@@ for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) { if (skip_prefix(line, sigcheck_gpg_status[i].check, &line)) { if (sigcheck_gpg_status[i].flags & GPG_STATUS_EXCLUSIVE) { - if (++seen_exclusive_status > 1) + if (seen_exclusive_status++) goto found_duplicate_status; } - sigc->result = sigcheck_gpg_status[i].result; - /* The trust messages are not followed by key/signer information */ - if (sigc->result != 'U') { + if (sigcheck_gpg_status[i].result) + sigc->result = sigcheck_gpg_status[i].result; + /* Do we have key information? */ + if (sigcheck_gpg_status[i].flags & GPG_STATUS_KEYID) { next = strchrnul(line, ' '); free(sigc->key); sigc->key = xmemdupz(line, next - line); - /* The ERRSIG message is not followed by signer information */ - if (*next && sigc->result != 'E') { + /* Do we have signer information? */ + if (*next && (sigcheck_gpg_status[i].flags & GPG_STATUS_UID)) { line = next + 1; next = strchrnul(line, '\n'); free(sigc->signer); sigc->signer = xmemdupz(line, next - line); } } + /* Do we have fingerprint? */ + if (sigcheck_gpg_status[i].flags & GPG_STATUS_FINGERPRINT) { + next = strchrnul(line, ' '); + free(sigc->fingerprint); + sigc->fingerprint = xmemdupz(line, next - line); + + /* Skip interim fields */ + for (j = 9; j > 0; j--) { + if (!*next) + break; + line = next + 1; + next = strchrnul(line, ' '); + } + + next = strchrnul(line, '\n'); + free(sigc->primary_key_fingerprint); + sigc->primary_key_fingerprint = xmemdupz(line, next - line); + } break; } @@@ -147,6 -178,8 +178,8 @@@ found_duplicate_status */ sigc->result = 'E'; /* Clear partial data to avoid confusion */ + FREE_AND_NULL(sigc->primary_key_fingerprint); + FREE_AND_NULL(sigc->fingerprint); FREE_AND_NULL(sigc->signer); FREE_AND_NULL(sigc->key); } diff --combined pretty.c index 8ca29e9281,53e4db12cf..b83a3ecd23 --- a/pretty.c +++ b/pretty.c @@@ -1256,6 -1256,14 +1256,14 @@@ static size_t format_commit_one(struct if (c->signature_check.key) strbuf_addstr(sb, c->signature_check.key); break; + case 'F': + if (c->signature_check.fingerprint) + strbuf_addstr(sb, c->signature_check.fingerprint); + break; + case 'P': + if (c->signature_check.primary_key_fingerprint) + strbuf_addstr(sb, c->signature_check.primary_key_fingerprint); + break; default: return 0; } @@@ -1304,9 -1312,6 +1312,9 @@@ if (skip_prefix(placeholder, "(trailers", &arg)) { struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; + + opts.no_divider = 1; + if (*arg == ':') { arg++; for (;;) {