@@ -524,10 +524,11 @@ static void add_merge_info(const struct pretty_print_context *pp,
524
524
strbuf_addch (sb , '\n' );
525
525
}
526
526
527
- static char * get_header (const struct commit * commit , const char * key )
527
+ static char * get_header (const struct commit * commit , const char * msg ,
528
+ const char * key )
528
529
{
529
530
int key_len = strlen (key );
530
- const char * line = commit -> buffer ;
531
+ const char * line = msg ;
531
532
532
533
while (line ) {
533
534
const char * eol = strchr (line , '\n' ), * next ;
@@ -588,25 +589,77 @@ char *logmsg_reencode(const struct commit *commit,
588
589
static const char * utf8 = "UTF-8" ;
589
590
const char * use_encoding ;
590
591
char * encoding ;
592
+ char * msg = commit -> buffer ;
591
593
char * out ;
592
594
595
+ if (!msg ) {
596
+ enum object_type type ;
597
+ unsigned long size ;
598
+
599
+ msg = read_sha1_file (commit -> object .sha1 , & type , & size );
600
+ if (!msg )
601
+ die ("Cannot read commit object %s" ,
602
+ sha1_to_hex (commit -> object .sha1 ));
603
+ if (type != OBJ_COMMIT )
604
+ die ("Expected commit for '%s', got %s" ,
605
+ sha1_to_hex (commit -> object .sha1 ), typename (type ));
606
+ }
607
+
593
608
if (!output_encoding || !* output_encoding )
594
- return NULL ;
595
- encoding = get_header (commit , "encoding" );
609
+ return msg ;
610
+ encoding = get_header (commit , msg , "encoding" );
596
611
use_encoding = encoding ? encoding : utf8 ;
597
- if (same_encoding (use_encoding , output_encoding ))
598
- if (encoding ) /* we'll strip encoding header later */
599
- out = xstrdup (commit -> buffer );
600
- else
601
- return NULL ; /* nothing to do */
602
- else
603
- out = reencode_string (commit -> buffer ,
604
- output_encoding , use_encoding );
612
+ if (same_encoding (use_encoding , output_encoding )) {
613
+ /*
614
+ * No encoding work to be done. If we have no encoding header
615
+ * at all, then there's nothing to do, and we can return the
616
+ * message verbatim (whether newly allocated or not).
617
+ */
618
+ if (!encoding )
619
+ return msg ;
620
+
621
+ /*
622
+ * Otherwise, we still want to munge the encoding header in the
623
+ * result, which will be done by modifying the buffer. If we
624
+ * are using a fresh copy, we can reuse it. But if we are using
625
+ * the cached copy from commit->buffer, we need to duplicate it
626
+ * to avoid munging commit->buffer.
627
+ */
628
+ out = msg ;
629
+ if (out == commit -> buffer )
630
+ out = xstrdup (out );
631
+ }
632
+ else {
633
+ /*
634
+ * There's actual encoding work to do. Do the reencoding, which
635
+ * still leaves the header to be replaced in the next step. At
636
+ * this point, we are done with msg. If we allocated a fresh
637
+ * copy, we can free it.
638
+ */
639
+ out = reencode_string (msg , output_encoding , use_encoding );
640
+ if (out && msg != commit -> buffer )
641
+ free (msg );
642
+ }
643
+
644
+ /*
645
+ * This replacement actually consumes the buffer we hand it, so we do
646
+ * not have to worry about freeing the old "out" here.
647
+ */
605
648
if (out )
606
649
out = replace_encoding_header (out , output_encoding );
607
650
608
651
free (encoding );
609
- return out ;
652
+ /*
653
+ * If the re-encoding failed, out might be NULL here; in that
654
+ * case we just return the commit message verbatim.
655
+ */
656
+ return out ? out : msg ;
657
+ }
658
+
659
+ void logmsg_free (char * msg , const struct commit * commit )
660
+ {
661
+ if (msg != commit -> buffer )
662
+ free (msg );
610
663
}
611
664
612
665
static int mailmap_name (const char * * email , size_t * email_len ,
@@ -1278,14 +1331,11 @@ void format_commit_message(const struct commit *commit,
1278
1331
context .pretty_ctx = pretty_ctx ;
1279
1332
context .wrap_start = sb -> len ;
1280
1333
context .message = logmsg_reencode (commit , output_enc );
1281
- if (!context .message )
1282
- context .message = commit -> buffer ;
1283
1334
1284
1335
strbuf_expand (sb , format , format_commit_item , & context );
1285
1336
rewrap_message_tail (sb , & context , 0 , 0 , 0 );
1286
1337
1287
- if (context .message != commit -> buffer )
1288
- free (context .message );
1338
+ logmsg_free (context .message , commit );
1289
1339
free (context .signature .gpg_output );
1290
1340
free (context .signature .signer );
1291
1341
}
@@ -1432,7 +1482,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
1432
1482
{
1433
1483
unsigned long beginning_of_body ;
1434
1484
int indent = 4 ;
1435
- const char * msg = commit -> buffer ;
1485
+ const char * msg ;
1436
1486
char * reencoded ;
1437
1487
const char * encoding ;
1438
1488
int need_8bit_cte = pp -> need_8bit_cte ;
@@ -1443,10 +1493,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
1443
1493
}
1444
1494
1445
1495
encoding = get_log_output_encoding ();
1446
- reencoded = logmsg_reencode (commit , encoding );
1447
- if (reencoded ) {
1448
- msg = reencoded ;
1449
- }
1496
+ msg = reencoded = logmsg_reencode (commit , encoding );
1450
1497
1451
1498
if (pp -> fmt == CMIT_FMT_ONELINE || pp -> fmt == CMIT_FMT_EMAIL )
1452
1499
indent = 0 ;
@@ -1503,7 +1550,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
1503
1550
if (pp -> fmt == CMIT_FMT_EMAIL && sb -> len <= beginning_of_body )
1504
1551
strbuf_addch (sb , '\n' );
1505
1552
1506
- free (reencoded );
1553
+ logmsg_free (reencoded , commit );
1507
1554
}
1508
1555
1509
1556
void pp_commit_easy (enum cmit_fmt fmt , const struct commit * commit ,
0 commit comments