]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'mg/gpg-fingerprint'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2018 15:53:58 +0000 (00:53 +0900)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2018 15:53:58 +0000 (00:53 +0900)
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

1  2 
gpg-interface.c
pretty.c

diff --combined gpg-interface.c
index d72a43b7748c470d82150776291c5a6a91857cd5,bea1aa2b5a7c4c22e435f2d45da4ddb6ef62bc9c..8ed274533f87198a74a3660809c25932fa43124a
@@@ -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 */
                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 8ca29e92815608437ccb1fb9909e78d5b4989529,53e4db12cf6f0d0db8561935aafe2801a9864c06..b83a3ecd2331af7f2e7e03bd76336cde3c2a6dfc
+++ 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;
                }
  
        if (skip_prefix(placeholder, "(trailers", &arg)) {
                struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
 +
 +              opts.no_divider = 1;
 +
                if (*arg == ':') {
                        arg++;
                        for (;;) {