@@ -100,9 +100,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
100
100
int quiet = 0 , source = 0 , mailmap = 0 ;
101
101
102
102
const struct option builtin_log_options [] = {
103
- OPT_BOOLEAN (0 , "quiet" , & quiet , N_ ("suppress diff output" )),
104
- OPT_BOOLEAN (0 , "source" , & source , N_ ("show source" )),
105
- OPT_BOOLEAN (0 , "use-mailmap" , & mailmap , N_ ("Use mail map file" )),
103
+ OPT_BOOL (0 , "quiet" , & quiet , N_ ("suppress diff output" )),
104
+ OPT_BOOL (0 , "source" , & source , N_ ("show source" )),
105
+ OPT_BOOL (0 , "use-mailmap" , & mailmap , N_ ("Use mail map file" )),
106
106
{ OPTION_CALLBACK , 0 , "decorate" , NULL , NULL , N_ ("decorate options" ),
107
107
PARSE_OPT_OPTARG , decorate_callback },
108
108
OPT_END ()
@@ -622,6 +622,14 @@ static void add_header(const char *value)
622
622
static int thread ;
623
623
static int do_signoff ;
624
624
static const char * signature = git_version_string ;
625
+ static int config_cover_letter ;
626
+
627
+ enum {
628
+ COVER_UNSET ,
629
+ COVER_OFF ,
630
+ COVER_ON ,
631
+ COVER_AUTO
632
+ };
625
633
626
634
static int git_format_config (const char * var , const char * value , void * cb )
627
635
{
@@ -683,6 +691,14 @@ static int git_format_config(const char *var, const char *value, void *cb)
683
691
}
684
692
if (!strcmp (var , "format.signature" ))
685
693
return git_config_string (& signature , var , value );
694
+ if (!strcmp (var , "format.coverletter" )) {
695
+ if (value && !strcasecmp (value , "auto" )) {
696
+ config_cover_letter = COVER_AUTO ;
697
+ return 0 ;
698
+ }
699
+ config_cover_letter = git_config_bool (var , value ) ? COVER_ON : COVER_OFF ;
700
+ return 0 ;
701
+ }
686
702
687
703
return git_log_config (var , value , cb );
688
704
}
@@ -794,9 +810,37 @@ static void add_branch_description(struct strbuf *buf, const char *branch_name)
794
810
}
795
811
}
796
812
813
+ static char * find_branch_name (struct rev_info * rev )
814
+ {
815
+ int i , positive = -1 ;
816
+ unsigned char branch_sha1 [20 ];
817
+ const unsigned char * tip_sha1 ;
818
+ const char * ref ;
819
+ char * full_ref , * branch = NULL ;
820
+
821
+ for (i = 0 ; i < rev -> cmdline .nr ; i ++ ) {
822
+ if (rev -> cmdline .rev [i ].flags & UNINTERESTING )
823
+ continue ;
824
+ if (positive < 0 )
825
+ positive = i ;
826
+ else
827
+ return NULL ;
828
+ }
829
+ if (positive < 0 )
830
+ return NULL ;
831
+ ref = rev -> cmdline .rev [positive ].name ;
832
+ tip_sha1 = rev -> cmdline .rev [positive ].item -> sha1 ;
833
+ if (dwim_ref (ref , strlen (ref ), branch_sha1 , & full_ref ) &&
834
+ !prefixcmp (full_ref , "refs/heads/" ) &&
835
+ !hashcmp (tip_sha1 , branch_sha1 ))
836
+ branch = xstrdup (full_ref + strlen ("refs/heads/" ));
837
+ free (full_ref );
838
+ return branch ;
839
+ }
840
+
797
841
static void make_cover_letter (struct rev_info * rev , int use_stdout ,
798
842
struct commit * origin ,
799
- int nr , struct commit * * list , struct commit * head ,
843
+ int nr , struct commit * * list ,
800
844
const char * branch_name ,
801
845
int quiet )
802
846
{
@@ -810,6 +854,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
810
854
struct diff_options opts ;
811
855
int need_8bit_cte = 0 ;
812
856
struct pretty_print_context pp = {0 };
857
+ struct commit * head = list [0 ];
813
858
814
859
if (rev -> commit_format != CMIT_FMT_EMAIL )
815
860
die (_ ("Cover letter needs email format" ));
@@ -827,6 +872,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
827
872
if (has_non_ascii (list [i ]-> buffer ))
828
873
need_8bit_cte = 1 ;
829
874
875
+ if (!branch_name )
876
+ branch_name = find_branch_name (rev );
877
+
830
878
msg = body ;
831
879
pp .fmt = CMIT_FMT_EMAIL ;
832
880
pp .date_mode = DATE_RFC2822 ;
@@ -1033,45 +1081,6 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)
1033
1081
return 0 ;
1034
1082
}
1035
1083
1036
- static char * find_branch_name (struct rev_info * rev )
1037
- {
1038
- int i , positive = -1 ;
1039
- unsigned char branch_sha1 [20 ];
1040
- const unsigned char * tip_sha1 ;
1041
- const char * ref ;
1042
- char * full_ref , * branch = NULL ;
1043
-
1044
- for (i = 0 ; i < rev -> cmdline .nr ; i ++ ) {
1045
- if (rev -> cmdline .rev [i ].flags & UNINTERESTING )
1046
- continue ;
1047
- if (positive < 0 )
1048
- positive = i ;
1049
- else
1050
- return NULL ;
1051
- }
1052
- if (0 <= positive ) {
1053
- ref = rev -> cmdline .rev [positive ].name ;
1054
- tip_sha1 = rev -> cmdline .rev [positive ].item -> sha1 ;
1055
- } else if (!rev -> cmdline .nr && rev -> pending .nr == 1 &&
1056
- !strcmp (rev -> pending .objects [0 ].name , "HEAD" )) {
1057
- /*
1058
- * No actual ref from command line, but "HEAD" from
1059
- * rev->def was added in setup_revisions()
1060
- * e.g. format-patch --cover-letter -12
1061
- */
1062
- ref = "HEAD" ;
1063
- tip_sha1 = rev -> pending .objects [0 ].item -> sha1 ;
1064
- } else {
1065
- return NULL ;
1066
- }
1067
- if (dwim_ref (ref , strlen (ref ), branch_sha1 , & full_ref ) &&
1068
- !prefixcmp (full_ref , "refs/heads/" ) &&
1069
- !hashcmp (tip_sha1 , branch_sha1 ))
1070
- branch = xstrdup (full_ref + strlen ("refs/heads/" ));
1071
- free (full_ref );
1072
- return branch ;
1073
- }
1074
-
1075
1084
int cmd_format_patch (int argc , const char * * argv , const char * prefix )
1076
1085
{
1077
1086
struct commit * commit ;
@@ -1083,10 +1092,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1083
1092
int start_number = -1 ;
1084
1093
int just_numbers = 0 ;
1085
1094
int ignore_if_in_upstream = 0 ;
1086
- int cover_letter = 0 ;
1095
+ int cover_letter = -1 ;
1087
1096
int boundary_count = 0 ;
1088
1097
int no_binary_diff = 0 ;
1089
- struct commit * origin = NULL , * head = NULL ;
1098
+ struct commit * origin = NULL ;
1090
1099
const char * in_reply_to = NULL ;
1091
1100
struct patch_ids ids ;
1092
1101
struct strbuf buf = STRBUF_INIT ;
@@ -1101,12 +1110,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1101
1110
{ OPTION_CALLBACK , 'N' , "no-numbered" , & numbered , NULL ,
1102
1111
N_ ("use [PATCH] even with multiple patches" ),
1103
1112
PARSE_OPT_NOARG , no_numbered_callback },
1104
- OPT_BOOLEAN ('s' , "signoff" , & do_signoff , N_ ("add Signed-off-by:" )),
1105
- OPT_BOOLEAN (0 , "stdout" , & use_stdout ,
1113
+ OPT_BOOL ('s' , "signoff" , & do_signoff , N_ ("add Signed-off-by:" )),
1114
+ OPT_BOOL (0 , "stdout" , & use_stdout ,
1106
1115
N_ ("print patches to standard out" )),
1107
- OPT_BOOLEAN (0 , "cover-letter" , & cover_letter ,
1116
+ OPT_BOOL (0 , "cover-letter" , & cover_letter ,
1108
1117
N_ ("generate a cover letter" )),
1109
- OPT_BOOLEAN (0 , "numbered-files" , & just_numbers ,
1118
+ OPT_BOOL (0 , "numbered-files" , & just_numbers ,
1110
1119
N_ ("use simple number sequence for output file names" )),
1111
1120
OPT_STRING (0 , "suffix" , & fmt_patch_suffix , N_ ("sfx" ),
1112
1121
N_ ("use <sfx> instead of '.patch'" )),
@@ -1280,28 +1289,36 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1280
1289
}
1281
1290
1282
1291
if (rev .pending .nr == 1 ) {
1292
+ int check_head = 0 ;
1293
+
1283
1294
if (rev .max_count < 0 && !rev .show_root_diff ) {
1284
1295
/*
1285
1296
* This is traditional behaviour of "git format-patch
1286
1297
* origin" that prepares what the origin side still
1287
1298
* does not have.
1288
1299
*/
1289
- unsigned char sha1 [20 ];
1290
- const char * ref ;
1291
-
1292
1300
rev .pending .objects [0 ].item -> flags |= UNINTERESTING ;
1293
1301
add_head_to_pending (& rev );
1294
- ref = resolve_ref_unsafe ("HEAD" , sha1 , 1 , NULL );
1295
- if (ref && !prefixcmp (ref , "refs/heads/" ))
1296
- branch_name = xstrdup (ref + strlen ("refs/heads/" ));
1297
- else
1298
- branch_name = xstrdup ("" ); /* no branch */
1302
+ check_head = 1 ;
1299
1303
}
1300
1304
/*
1301
1305
* Otherwise, it is "format-patch -22 HEAD", and/or
1302
1306
* "format-patch --root HEAD". The user wants
1303
1307
* get_revision() to do the usual traversal.
1304
1308
*/
1309
+
1310
+ if (!strcmp (rev .pending .objects [0 ].name , "HEAD" ))
1311
+ check_head = 1 ;
1312
+
1313
+ if (check_head ) {
1314
+ unsigned char sha1 [20 ];
1315
+ const char * ref ;
1316
+ ref = resolve_ref_unsafe ("HEAD" , sha1 , 1 , NULL );
1317
+ if (ref && !prefixcmp (ref , "refs/heads/" ))
1318
+ branch_name = xstrdup (ref + strlen ("refs/heads/" ));
1319
+ else
1320
+ branch_name = xstrdup ("" ); /* no branch */
1321
+ }
1305
1322
}
1306
1323
1307
1324
/*
@@ -1310,29 +1327,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1310
1327
*/
1311
1328
rev .show_root_diff = 1 ;
1312
1329
1313
- if (cover_letter ) {
1314
- /*
1315
- * NEEDSWORK:randomly pick one positive commit to show
1316
- * diffstat; this is often the tip and the command
1317
- * happens to do the right thing in most cases, but a
1318
- * complex command like "--cover-letter a b c ^bottom"
1319
- * picks "c" and shows diffstat between bottom..c
1320
- * which may not match what the series represents at
1321
- * all and totally broken.
1322
- */
1323
- int i ;
1324
- for (i = 0 ; i < rev .pending .nr ; i ++ ) {
1325
- struct object * o = rev .pending .objects [i ].item ;
1326
- if (!(o -> flags & UNINTERESTING ))
1327
- head = (struct commit * )o ;
1328
- }
1329
- /* There is nothing to show; it is not an error, though. */
1330
- if (!head )
1331
- return 0 ;
1332
- if (!branch_name )
1333
- branch_name = find_branch_name (& rev );
1334
- }
1335
-
1336
1330
if (ignore_if_in_upstream ) {
1337
1331
/* Don't say anything if head and upstream are the same. */
1338
1332
if (rev .pending .nr == 2 ) {
@@ -1364,11 +1358,21 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1364
1358
list = xrealloc (list , nr * sizeof (list [0 ]));
1365
1359
list [nr - 1 ] = commit ;
1366
1360
}
1361
+ if (nr == 0 )
1362
+ /* nothing to do */
1363
+ return 0 ;
1367
1364
total = nr ;
1368
1365
if (!keep_subject && auto_number && total > 1 )
1369
1366
numbered = 1 ;
1370
1367
if (numbered )
1371
1368
rev .total = total + start_number - 1 ;
1369
+ if (cover_letter == -1 ) {
1370
+ if (config_cover_letter == COVER_AUTO )
1371
+ cover_letter = (total > 1 );
1372
+ else
1373
+ cover_letter = (config_cover_letter == COVER_ON );
1374
+ }
1375
+
1372
1376
if (in_reply_to || thread || cover_letter )
1373
1377
rev .ref_message_ids = xcalloc (1 , sizeof (struct string_list ));
1374
1378
if (in_reply_to ) {
@@ -1381,7 +1385,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1381
1385
if (thread )
1382
1386
gen_message_id (& rev , "cover" );
1383
1387
make_cover_letter (& rev , use_stdout ,
1384
- origin , nr , list , head , branch_name , quiet );
1388
+ origin , nr , list , branch_name , quiet );
1385
1389
total ++ ;
1386
1390
start_number -- ;
1387
1391
}
0 commit comments