@@ -445,6 +445,7 @@ struct format_commit_context {
445445 enum date_mode dmode ;
446446 unsigned commit_header_parsed :1 ;
447447 unsigned commit_message_parsed :1 ;
448+ size_t width , indent1 , indent2 ;
448449
449450 /* These offsets are relative to the start of the commit message. */
450451 struct chunk author ;
@@ -458,6 +459,7 @@ struct format_commit_context {
458459 struct chunk abbrev_commit_hash ;
459460 struct chunk abbrev_tree_hash ;
460461 struct chunk abbrev_parent_hashes ;
462+ size_t wrap_start ;
461463};
462464
463465static int add_again (struct strbuf * sb , struct chunk * chunk )
@@ -595,6 +597,35 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
595597 strbuf_addch (sb , ')' );
596598}
597599
600+ static void strbuf_wrap (struct strbuf * sb , size_t pos ,
601+ size_t width , size_t indent1 , size_t indent2 )
602+ {
603+ struct strbuf tmp = STRBUF_INIT ;
604+
605+ if (pos )
606+ strbuf_add (& tmp , sb -> buf , pos );
607+ strbuf_add_wrapped_text (& tmp , sb -> buf + pos ,
608+ (int ) indent1 , (int ) indent2 , (int ) width );
609+ strbuf_swap (& tmp , sb );
610+ strbuf_release (& tmp );
611+ }
612+
613+ static void rewrap_message_tail (struct strbuf * sb ,
614+ struct format_commit_context * c ,
615+ size_t new_width , size_t new_indent1 ,
616+ size_t new_indent2 )
617+ {
618+ if (c -> width == new_width && c -> indent1 == new_indent1 &&
619+ c -> indent2 == new_indent2 )
620+ return ;
621+ if (c -> wrap_start && c -> wrap_start < sb -> len )
622+ strbuf_wrap (sb , c -> wrap_start , c -> width , c -> indent1 , c -> indent2 );
623+ c -> wrap_start = sb -> len ;
624+ c -> width = new_width ;
625+ c -> indent1 = new_indent1 ;
626+ c -> indent2 = new_indent2 ;
627+ }
628+
598629static size_t format_commit_item (struct strbuf * sb , const char * placeholder ,
599630 void * context )
600631{
@@ -645,6 +676,30 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
645676 return 3 ;
646677 } else
647678 return 0 ;
679+ case 'w' :
680+ if (placeholder [1 ] == '(' ) {
681+ unsigned long width = 0 , indent1 = 0 , indent2 = 0 ;
682+ char * next ;
683+ const char * start = placeholder + 2 ;
684+ const char * end = strchr (start , ')' );
685+ if (!end )
686+ return 0 ;
687+ if (end > start ) {
688+ width = strtoul (start , & next , 10 );
689+ if (* next == ',' ) {
690+ indent1 = strtoul (next + 1 , & next , 10 );
691+ if (* next == ',' ) {
692+ indent2 = strtoul (next + 1 ,
693+ & next , 10 );
694+ }
695+ }
696+ if (* next != ')' )
697+ return 0 ;
698+ }
699+ rewrap_message_tail (sb , c , width , indent1 , indent2 );
700+ return end - placeholder + 1 ;
701+ } else
702+ return 0 ;
648703 }
649704
650705 /* these depend on the commit */
@@ -748,7 +803,9 @@ void format_commit_message(const struct commit *commit,
748803 memset (& context , 0 , sizeof (context ));
749804 context .commit = commit ;
750805 context .dmode = dmode ;
806+ context .wrap_start = sb -> len ;
751807 strbuf_expand (sb , format , format_commit_item , & context );
808+ rewrap_message_tail (sb , & context , 0 , 0 , 0 );
752809}
753810
754811static void pp_header (enum cmit_fmt fmt ,
0 commit comments