22#include "tag.h"
33#include "commit.h"
44#include "pkt-line.h"
5+ #include "utf8.h"
56
67int save_commit_buffer = 1 ;
78
@@ -597,17 +598,72 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com
597598 return offset ;
598599}
599600
600- unsigned long pretty_print_commit (enum cmit_fmt fmt , const struct commit * commit ,
601- unsigned long len , char * buf , unsigned long space ,
601+ static char * get_header (const struct commit * commit , const char * key )
602+ {
603+ int key_len = strlen (key );
604+ const char * line = commit -> buffer ;
605+
606+ for (;;) {
607+ const char * eol = strchr (line , '\n' ), * next ;
608+
609+ if (line == eol )
610+ return NULL ;
611+ if (!eol ) {
612+ eol = line + strlen (line );
613+ next = NULL ;
614+ } else
615+ next = eol + 1 ;
616+ if (!strncmp (line , key , key_len ) && line [key_len ] == ' ' ) {
617+ int len = eol - line - key_len ;
618+ char * ret = xmalloc (len );
619+ memcpy (ret , line + key_len + 1 , len - 1 );
620+ ret [len - 1 ] = '\0' ;
621+ return ret ;
622+ }
623+ line = next ;
624+ }
625+ }
626+
627+ static char * logmsg_reencode (const struct commit * commit )
628+ {
629+ char * encoding ;
630+ char * out ;
631+ char * output_encoding = (git_log_output_encoding
632+ ? git_log_output_encoding
633+ : git_commit_encoding );
634+
635+ if (!output_encoding )
636+ return NULL ;
637+ encoding = get_header (commit , "encoding" );
638+ if (!encoding || !strcmp (encoding , output_encoding )) {
639+ free (encoding );
640+ return NULL ;
641+ }
642+ out = reencode_string (commit -> buffer , output_encoding , encoding );
643+ free (encoding );
644+ if (!out )
645+ return NULL ;
646+ return out ;
647+ }
648+
649+ unsigned long pretty_print_commit (enum cmit_fmt fmt ,
650+ const struct commit * commit ,
651+ unsigned long len ,
652+ char * buf , unsigned long space ,
602653 int abbrev , const char * subject ,
603- const char * after_subject , int relative_date )
654+ const char * after_subject ,
655+ int relative_date )
604656{
605657 int hdr = 1 , body = 0 ;
606658 unsigned long offset = 0 ;
607659 int indent = 4 ;
608660 int parents_shown = 0 ;
609661 const char * msg = commit -> buffer ;
610662 int plain_non_ascii = 0 ;
663+ char * reencoded = logmsg_reencode (commit );
664+
665+ if (reencoded )
666+ msg = reencoded ;
611667
612668 if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL )
613669 indent = 0 ;
@@ -624,7 +680,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
624680 for (in_body = i = 0 ; (ch = msg [i ]) && i < len ; i ++ ) {
625681 if (!in_body ) {
626682 /* author could be non 7-bit ASCII but
627- * the log may so; skip over the
683+ * the log may be so; skip over the
628684 * header part first.
629685 */
630686 if (ch == '\n' &&
@@ -755,6 +811,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
755811 if (fmt == CMIT_FMT_EMAIL && !body )
756812 buf [offset ++ ] = '\n' ;
757813 buf [offset ] = '\0' ;
814+
815+ free (reencoded );
758816 return offset ;
759817}
760818
0 commit comments