@@ -443,6 +443,78 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
443443 strbuf_release (& signature );
444444}
445445
446+ static int which_parent (const unsigned char * sha1 , const struct commit * commit )
447+ {
448+ int nth ;
449+ const struct commit_list * parent ;
450+
451+ for (nth = 0 , parent = commit -> parents ; parent ; parent = parent -> next ) {
452+ if (!hashcmp (parent -> item -> object .sha1 , sha1 ))
453+ return nth ;
454+ nth ++ ;
455+ }
456+ return -1 ;
457+ }
458+
459+ static void show_one_mergetag (struct rev_info * opt ,
460+ struct commit_extra_header * extra ,
461+ struct commit * commit )
462+ {
463+ unsigned char sha1 [20 ];
464+ struct tag * tag ;
465+ struct strbuf verify_message ;
466+ int status , nth ;
467+ size_t payload_size , gpg_message_offset ;
468+
469+ hash_sha1_file (extra -> value , extra -> len , typename (OBJ_TAG ), sha1 );
470+ tag = lookup_tag (sha1 );
471+ if (!tag )
472+ return ; /* error message already given */
473+
474+ strbuf_init (& verify_message , 256 );
475+ if (parse_tag_buffer (tag , extra -> value , extra -> len ))
476+ strbuf_addstr (& verify_message , "malformed mergetag\n" );
477+ else if ((nth = which_parent (tag -> tagged -> sha1 , commit )) < 0 )
478+ strbuf_addf (& verify_message , "tag %s names a non-parent %s\n" ,
479+ tag -> tag , tag -> tagged -> sha1 );
480+ else
481+ strbuf_addf (& verify_message ,
482+ "parent #%d, tagged '%s'\n" , nth + 1 , tag -> tag );
483+ gpg_message_offset = verify_message .len ;
484+
485+ payload_size = parse_signature (extra -> value , extra -> len );
486+ if ((extra -> len <= payload_size ) ||
487+ (verify_signed_buffer (extra -> value , payload_size ,
488+ extra -> value + payload_size ,
489+ extra -> len - payload_size ,
490+ & verify_message ) &&
491+ verify_message .len <= gpg_message_offset )) {
492+ strbuf_addstr (& verify_message , "No signature\n" );
493+ status = -1 ;
494+ }
495+ else if (strstr (verify_message .buf + gpg_message_offset ,
496+ ": Good signature from " ))
497+ status = 0 ;
498+ else
499+ status = -1 ;
500+
501+ show_sig_lines (opt , status , verify_message .buf );
502+ strbuf_release (& verify_message );
503+ }
504+
505+ static void show_mergetag (struct rev_info * opt , struct commit * commit )
506+ {
507+ struct commit_extra_header * extra , * to_free ;
508+
509+ to_free = read_commit_extra_headers (commit , NULL );
510+ for (extra = to_free ; extra ; extra = extra -> next ) {
511+ if (strcmp (extra -> key , "mergetag" ))
512+ continue ; /* not a merge tag */
513+ show_one_mergetag (opt , extra , commit );
514+ }
515+ free_commit_extra_headers (to_free );
516+ }
517+
446518void show_log (struct rev_info * opt )
447519{
448520 struct strbuf msgbuf = STRBUF_INIT ;
@@ -554,8 +626,10 @@ void show_log(struct rev_info *opt)
554626 }
555627 }
556628
557- if (opt -> show_signature )
629+ if (opt -> show_signature ) {
558630 show_signature (opt , commit );
631+ show_mergetag (opt , commit );
632+ }
559633
560634 if (!commit -> buffer )
561635 return ;
0 commit comments