@@ -446,6 +446,7 @@ struct format_commit_context {
446446 const struct pretty_print_context * pretty_ctx ;
447447 unsigned commit_header_parsed :1 ;
448448 unsigned commit_message_parsed :1 ;
449+ size_t width , indent1 , indent2 ;
449450
450451 /* These offsets are relative to the start of the commit message. */
451452 struct chunk author ;
@@ -459,6 +460,7 @@ struct format_commit_context {
459460 struct chunk abbrev_commit_hash ;
460461 struct chunk abbrev_tree_hash ;
461462 struct chunk abbrev_parent_hashes ;
463+ size_t wrap_start ;
462464};
463465
464466static int add_again (struct strbuf * sb , struct chunk * chunk )
@@ -596,6 +598,35 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
596598 strbuf_addch (sb , ')' );
597599}
598600
601+ static void strbuf_wrap (struct strbuf * sb , size_t pos ,
602+ size_t width , size_t indent1 , size_t indent2 )
603+ {
604+ struct strbuf tmp = STRBUF_INIT ;
605+
606+ if (pos )
607+ strbuf_add (& tmp , sb -> buf , pos );
608+ strbuf_add_wrapped_text (& tmp , sb -> buf + pos ,
609+ (int ) indent1 , (int ) indent2 , (int ) width );
610+ strbuf_swap (& tmp , sb );
611+ strbuf_release (& tmp );
612+ }
613+
614+ static void rewrap_message_tail (struct strbuf * sb ,
615+ struct format_commit_context * c ,
616+ size_t new_width , size_t new_indent1 ,
617+ size_t new_indent2 )
618+ {
619+ if (c -> width == new_width && c -> indent1 == new_indent1 &&
620+ c -> indent2 == new_indent2 )
621+ return ;
622+ if (c -> wrap_start < sb -> len )
623+ strbuf_wrap (sb , c -> wrap_start , c -> width , c -> indent1 , c -> indent2 );
624+ c -> wrap_start = sb -> len ;
625+ c -> width = new_width ;
626+ c -> indent1 = new_indent1 ;
627+ c -> indent2 = new_indent2 ;
628+ }
629+
599630static size_t format_commit_item (struct strbuf * sb , const char * placeholder ,
600631 void * context )
601632{
@@ -646,6 +677,30 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
646677 return 3 ;
647678 } else
648679 return 0 ;
680+ case 'w' :
681+ if (placeholder [1 ] == '(' ) {
682+ unsigned long width = 0 , indent1 = 0 , indent2 = 0 ;
683+ char * next ;
684+ const char * start = placeholder + 2 ;
685+ const char * end = strchr (start , ')' );
686+ if (!end )
687+ return 0 ;
688+ if (end > start ) {
689+ width = strtoul (start , & next , 10 );
690+ if (* next == ',' ) {
691+ indent1 = strtoul (next + 1 , & next , 10 );
692+ if (* next == ',' ) {
693+ indent2 = strtoul (next + 1 ,
694+ & next , 10 );
695+ }
696+ }
697+ if (* next != ')' )
698+ return 0 ;
699+ }
700+ rewrap_message_tail (sb , c , width , indent1 , indent2 );
701+ return end - placeholder + 1 ;
702+ } else
703+ return 0 ;
649704 }
650705
651706 /* these depend on the commit */
@@ -765,7 +820,9 @@ void format_commit_message(const struct commit *commit,
765820 memset (& context , 0 , sizeof (context ));
766821 context .commit = commit ;
767822 context .pretty_ctx = pretty_ctx ;
823+ context .wrap_start = sb -> len ;
768824 strbuf_expand (sb , format , format_commit_item , & context );
825+ rewrap_message_tail (sb , & context , 0 , 0 , 0 );
769826}
770827
771828static void pp_header (enum cmit_fmt fmt ,
0 commit comments