3737#include "range-diff.h"
3838
3939#define MAIL_DEFAULT_WRAP 72
40+ #define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
4041
4142/* Set a default date-time format for git log ("log.date" config variable) */
4243static const char * default_date_mode = NULL ;
@@ -777,6 +778,13 @@ enum thread_level {
777778 THREAD_DEEP
778779};
779780
781+ enum cover_from_description {
782+ COVER_FROM_NONE ,
783+ COVER_FROM_MESSAGE ,
784+ COVER_FROM_SUBJECT ,
785+ COVER_FROM_AUTO
786+ };
787+
780788static enum thread_level thread ;
781789static int do_signoff ;
782790static int base_auto ;
@@ -785,6 +793,23 @@ static const char *signature = git_version_string;
785793static const char * signature_file ;
786794static enum cover_setting config_cover_letter ;
787795static const char * config_output_directory ;
796+ static enum cover_from_description cover_from_description_mode = COVER_FROM_MESSAGE ;
797+
798+ static enum cover_from_description parse_cover_from_description (const char * arg )
799+ {
800+ if (!arg || !strcmp (arg , "default" ))
801+ return COVER_FROM_MESSAGE ;
802+ else if (!strcmp (arg , "none" ))
803+ return COVER_FROM_NONE ;
804+ else if (!strcmp (arg , "message" ))
805+ return COVER_FROM_MESSAGE ;
806+ else if (!strcmp (arg , "subject" ))
807+ return COVER_FROM_SUBJECT ;
808+ else if (!strcmp (arg , "auto" ))
809+ return COVER_FROM_AUTO ;
810+ else
811+ die (_ ("%s: invalid cover from description mode" ), arg );
812+ }
788813
789814static int git_format_config (const char * var , const char * value , void * cb )
790815{
@@ -891,6 +916,10 @@ static int git_format_config(const char *var, const char *value, void *cb)
891916 }
892917 return 0 ;
893918 }
919+ if (!strcmp (var , "format.coverfromdescription" )) {
920+ cover_from_description_mode = parse_cover_from_description (value );
921+ return 0 ;
922+ }
894923
895924 return git_log_config (var , value , cb );
896925}
@@ -997,20 +1026,6 @@ static void print_signature(FILE *file)
9971026 putc ('\n' , file );
9981027}
9991028
1000- static void add_branch_description (struct strbuf * buf , const char * branch_name )
1001- {
1002- struct strbuf desc = STRBUF_INIT ;
1003- if (!branch_name || !* branch_name )
1004- return ;
1005- read_branch_desc (& desc , branch_name );
1006- if (desc .len ) {
1007- strbuf_addch (buf , '\n' );
1008- strbuf_addbuf (buf , & desc );
1009- strbuf_addch (buf , '\n' );
1010- }
1011- strbuf_release (& desc );
1012- }
1013-
10141029static char * find_branch_name (struct rev_info * rev )
10151030{
10161031 int i , positive = -1 ;
@@ -1057,15 +1072,51 @@ static void show_diffstat(struct rev_info *rev,
10571072 fprintf (rev -> diffopt .file , "\n" );
10581073}
10591074
1075+ static void prepare_cover_text (struct pretty_print_context * pp ,
1076+ const char * branch_name ,
1077+ struct strbuf * sb ,
1078+ const char * encoding ,
1079+ int need_8bit_cte )
1080+ {
1081+ const char * subject = "*** SUBJECT HERE ***" ;
1082+ const char * body = "*** BLURB HERE ***" ;
1083+ struct strbuf description_sb = STRBUF_INIT ;
1084+ struct strbuf subject_sb = STRBUF_INIT ;
1085+
1086+ if (cover_from_description_mode == COVER_FROM_NONE )
1087+ goto do_pp ;
1088+
1089+ if (branch_name && * branch_name )
1090+ read_branch_desc (& description_sb , branch_name );
1091+ if (!description_sb .len )
1092+ goto do_pp ;
1093+
1094+ if (cover_from_description_mode == COVER_FROM_SUBJECT ||
1095+ cover_from_description_mode == COVER_FROM_AUTO )
1096+ body = format_subject (& subject_sb , description_sb .buf , " " );
1097+
1098+ if (cover_from_description_mode == COVER_FROM_MESSAGE ||
1099+ (cover_from_description_mode == COVER_FROM_AUTO &&
1100+ subject_sb .len > COVER_FROM_AUTO_MAX_SUBJECT_LEN ))
1101+ body = description_sb .buf ;
1102+ else
1103+ subject = subject_sb .buf ;
1104+
1105+ do_pp :
1106+ pp_title_line (pp , & subject , sb , encoding , need_8bit_cte );
1107+ pp_remainder (pp , & body , sb , 0 );
1108+
1109+ strbuf_release (& description_sb );
1110+ strbuf_release (& subject_sb );
1111+ }
1112+
10601113static void make_cover_letter (struct rev_info * rev , int use_stdout ,
10611114 struct commit * origin ,
10621115 int nr , struct commit * * list ,
10631116 const char * branch_name ,
10641117 int quiet )
10651118{
10661119 const char * committer ;
1067- const char * body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n" ;
1068- const char * msg ;
10691120 struct shortlog log ;
10701121 struct strbuf sb = STRBUF_INIT ;
10711122 int i ;
@@ -1095,15 +1146,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
10951146 if (!branch_name )
10961147 branch_name = find_branch_name (rev );
10971148
1098- msg = body ;
10991149 pp .fmt = CMIT_FMT_EMAIL ;
11001150 pp .date_mode .type = DATE_RFC2822 ;
11011151 pp .rev = rev ;
11021152 pp .print_email_subject = 1 ;
11031153 pp_user_info (& pp , NULL , & sb , committer , encoding );
1104- pp_title_line (& pp , & msg , & sb , encoding , need_8bit_cte );
1105- pp_remainder (& pp , & msg , & sb , 0 );
1106- add_branch_description (& sb , branch_name );
1154+ prepare_cover_text (& pp , branch_name , & sb , encoding , need_8bit_cte );
11071155 fprintf (rev -> diffopt .file , "%s\n" , sb .buf );
11081156
11091157 strbuf_release (& sb );
@@ -1545,6 +1593,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
15451593 int use_patch_format = 0 ;
15461594 int quiet = 0 ;
15471595 int reroll_count = -1 ;
1596+ char * cover_from_description_arg = NULL ;
15481597 char * branch_name = NULL ;
15491598 char * base_commit = NULL ;
15501599 struct base_tree_info bases ;
@@ -1581,6 +1630,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
15811630 { OPTION_CALLBACK , 0 , "rfc" , & rev , NULL ,
15821631 N_ ("Use [RFC PATCH] instead of [PATCH]" ),
15831632 PARSE_OPT_NOARG | PARSE_OPT_NONEG , rfc_callback },
1633+ OPT_STRING (0 , "cover-from-description" , & cover_from_description_arg ,
1634+ N_ ("cover-from-description-mode" ),
1635+ N_ ("generate parts of a cover letter based on a branch's description" )),
15841636 { OPTION_CALLBACK , 0 , "subject-prefix" , & rev , N_ ("prefix" ),
15851637 N_ ("Use [<prefix>] instead of [PATCH]" ),
15861638 PARSE_OPT_NONEG , subject_prefix_callback },
@@ -1672,6 +1724,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
16721724 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
16731725 PARSE_OPT_KEEP_DASHDASH );
16741726
1727+ if (cover_from_description_arg )
1728+ cover_from_description_mode = parse_cover_from_description (cover_from_description_arg );
1729+
16751730 if (0 < reroll_count ) {
16761731 struct strbuf sprefix = STRBUF_INIT ;
16771732 strbuf_addf (& sprefix , "%s v%d" ,
0 commit comments