37
37
#include "range-diff.h"
38
38
39
39
#define MAIL_DEFAULT_WRAP 72
40
+ #define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
40
41
41
42
/* Set a default date-time format for git log ("log.date" config variable) */
42
43
static const char * default_date_mode = NULL ;
@@ -777,6 +778,13 @@ enum thread_level {
777
778
THREAD_DEEP
778
779
};
779
780
781
+ enum cover_from_description {
782
+ COVER_FROM_NONE ,
783
+ COVER_FROM_MESSAGE ,
784
+ COVER_FROM_SUBJECT ,
785
+ COVER_FROM_AUTO
786
+ };
787
+
780
788
static enum thread_level thread ;
781
789
static int do_signoff ;
782
790
static int base_auto ;
@@ -785,6 +793,23 @@ static const char *signature = git_version_string;
785
793
static const char * signature_file ;
786
794
static enum cover_setting config_cover_letter ;
787
795
static 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
+ }
788
813
789
814
static int git_format_config (const char * var , const char * value , void * cb )
790
815
{
@@ -891,6 +916,10 @@ static int git_format_config(const char *var, const char *value, void *cb)
891
916
}
892
917
return 0 ;
893
918
}
919
+ if (!strcmp (var , "format.coverfromdescription" )) {
920
+ cover_from_description_mode = parse_cover_from_description (value );
921
+ return 0 ;
922
+ }
894
923
895
924
return git_log_config (var , value , cb );
896
925
}
@@ -997,20 +1026,6 @@ static void print_signature(FILE *file)
997
1026
putc ('\n' , file );
998
1027
}
999
1028
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
-
1014
1029
static char * find_branch_name (struct rev_info * rev )
1015
1030
{
1016
1031
int i , positive = -1 ;
@@ -1057,15 +1072,51 @@ static void show_diffstat(struct rev_info *rev,
1057
1072
fprintf (rev -> diffopt .file , "\n" );
1058
1073
}
1059
1074
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
+
1060
1113
static void make_cover_letter (struct rev_info * rev , int use_stdout ,
1061
1114
struct commit * origin ,
1062
1115
int nr , struct commit * * list ,
1063
1116
const char * branch_name ,
1064
1117
int quiet )
1065
1118
{
1066
1119
const char * committer ;
1067
- const char * body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n" ;
1068
- const char * msg ;
1069
1120
struct shortlog log ;
1070
1121
struct strbuf sb = STRBUF_INIT ;
1071
1122
int i ;
@@ -1095,15 +1146,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
1095
1146
if (!branch_name )
1096
1147
branch_name = find_branch_name (rev );
1097
1148
1098
- msg = body ;
1099
1149
pp .fmt = CMIT_FMT_EMAIL ;
1100
1150
pp .date_mode .type = DATE_RFC2822 ;
1101
1151
pp .rev = rev ;
1102
1152
pp .print_email_subject = 1 ;
1103
1153
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 );
1107
1155
fprintf (rev -> diffopt .file , "%s\n" , sb .buf );
1108
1156
1109
1157
strbuf_release (& sb );
@@ -1545,6 +1593,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1545
1593
int use_patch_format = 0 ;
1546
1594
int quiet = 0 ;
1547
1595
int reroll_count = -1 ;
1596
+ char * cover_from_description_arg = NULL ;
1548
1597
char * branch_name = NULL ;
1549
1598
char * base_commit = NULL ;
1550
1599
struct base_tree_info bases ;
@@ -1581,6 +1630,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1581
1630
{ OPTION_CALLBACK , 0 , "rfc" , & rev , NULL ,
1582
1631
N_ ("Use [RFC PATCH] instead of [PATCH]" ),
1583
1632
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" )),
1584
1636
{ OPTION_CALLBACK , 0 , "subject-prefix" , & rev , N_ ("prefix" ),
1585
1637
N_ ("Use [<prefix>] instead of [PATCH]" ),
1586
1638
PARSE_OPT_NONEG , subject_prefix_callback },
@@ -1672,6 +1724,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1672
1724
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
1673
1725
PARSE_OPT_KEEP_DASHDASH );
1674
1726
1727
+ if (cover_from_description_arg )
1728
+ cover_from_description_mode = parse_cover_from_description (cover_from_description_arg );
1729
+
1675
1730
if (0 < reroll_count ) {
1676
1731
struct strbuf sprefix = STRBUF_INIT ;
1677
1732
strbuf_addf (& sprefix , "%s v%d" ,
0 commit comments