@@ -417,13 +417,6 @@ int cmd_log(int argc, const char **argv, const char *prefix)
417417}
418418
419419/* format-patch */
420- #define FORMAT_PATCH_NAME_MAX 64
421-
422- static int istitlechar (char c )
423- {
424- return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) ||
425- (c >= '0' && c <= '9' ) || c == '.' || c == '_' ;
426- }
427420
428421static const char * fmt_patch_suffix = ".patch" ;
429422static int numbered = 0 ;
@@ -523,92 +516,33 @@ static int git_format_config(const char *var, const char *value, void *cb)
523516 return git_log_config (var , value , cb );
524517}
525518
526-
527- static const char * get_oneline_for_filename (struct commit * commit ,
528- int keep_subject )
529- {
530- static char filename [PATH_MAX ];
531- char * sol ;
532- int len = 0 ;
533- int suffix_len = strlen (fmt_patch_suffix ) + 1 ;
534-
535- sol = strstr (commit -> buffer , "\n\n" );
536- if (!sol )
537- filename [0 ] = '\0' ;
538- else {
539- int j , space = 0 ;
540-
541- sol += 2 ;
542- /* strip [PATCH] or [PATCH blabla] */
543- if (!keep_subject && !prefixcmp (sol , "[PATCH" )) {
544- char * eos = strchr (sol + 6 , ']' );
545- if (eos ) {
546- while (isspace (* eos ))
547- eos ++ ;
548- sol = eos ;
549- }
550- }
551-
552- for (j = 0 ;
553- j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
554- len < sizeof (filename ) - suffix_len &&
555- sol [j ] && sol [j ] != '\n' ;
556- j ++ ) {
557- if (istitlechar (sol [j ])) {
558- if (space ) {
559- filename [len ++ ] = '-' ;
560- space = 0 ;
561- }
562- filename [len ++ ] = sol [j ];
563- if (sol [j ] == '.' )
564- while (sol [j + 1 ] == '.' )
565- j ++ ;
566- } else
567- space = 1 ;
568- }
569- while (filename [len - 1 ] == '.'
570- || filename [len - 1 ] == '-' )
571- len -- ;
572- filename [len ] = '\0' ;
573- }
574- return filename ;
575- }
576-
577519static FILE * realstdout = NULL ;
578520static const char * output_directory = NULL ;
579521static int outdir_offset ;
580522
581- static int reopen_stdout (const char * oneline , int nr , struct rev_info * rev )
523+ static int reopen_stdout (struct commit * commit , struct rev_info * rev )
582524{
583- char filename [PATH_MAX ];
584- int len = 0 ;
525+ struct strbuf filename = STRBUF_INIT ;
585526 int suffix_len = strlen (fmt_patch_suffix ) + 1 ;
586527
587528 if (output_directory ) {
588- len = snprintf (filename , sizeof (filename ), "%s" ,
589- output_directory );
590- if (len >=
591- sizeof (filename ) - FORMAT_PATCH_NAME_MAX - suffix_len )
529+ strbuf_addstr (& filename , output_directory );
530+ if (filename .len >=
531+ PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len )
592532 return error ("name of output directory is too long" );
593- if (filename [ len - 1 ] != '/' )
594- filename [ len ++ ] = '/' ;
533+ if (filename . buf [ filename . len - 1 ] != '/' )
534+ strbuf_addch ( & filename , '/' ) ;
595535 }
596536
597- if (!oneline )
598- len += sprintf (filename + len , "%d" , nr );
599- else {
600- len += sprintf (filename + len , "%04d-" , nr );
601- len += snprintf (filename + len , sizeof (filename ) - len - 1
602- - suffix_len , "%s" , oneline );
603- strcpy (filename + len , fmt_patch_suffix );
604- }
537+ get_patch_filename (commit , rev -> nr , fmt_patch_suffix , & filename );
605538
606539 if (!DIFF_OPT_TST (& rev -> diffopt , QUIET ))
607- fprintf (realstdout , "%s\n" , filename + outdir_offset );
540+ fprintf (realstdout , "%s\n" , filename . buf + outdir_offset );
608541
609- if (freopen (filename , "w" , stdout ) == NULL )
610- return error ("Cannot open patch file %s" ,filename );
542+ if (freopen (filename . buf , "w" , stdout ) == NULL )
543+ return error ("Cannot open patch file %s" , filename . buf );
611544
545+ strbuf_release (& filename );
612546 return 0 ;
613547}
614548
@@ -678,7 +612,6 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
678612 int nr , struct commit * * list , struct commit * head )
679613{
680614 const char * committer ;
681- char * head_sha1 ;
682615 const char * subject_start = NULL ;
683616 const char * body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n" ;
684617 const char * msg ;
@@ -689,20 +622,40 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
689622 const char * encoding = "utf-8" ;
690623 struct diff_options opts ;
691624 int need_8bit_cte = 0 ;
625+ struct commit * commit = NULL ;
692626
693627 if (rev -> commit_format != CMIT_FMT_EMAIL )
694628 die ("Cover letter needs email format" );
695629
696- if (!use_stdout && reopen_stdout (numbered_files ?
697- NULL : "cover-letter" , 0 , rev ))
630+ committer = git_committer_info (0 );
631+
632+ if (!numbered_files ) {
633+ /*
634+ * We fake a commit for the cover letter so we get the filename
635+ * desired.
636+ */
637+ commit = xcalloc (1 , sizeof (* commit ));
638+ commit -> buffer = xmalloc (400 );
639+ snprintf (commit -> buffer , 400 ,
640+ "tree 0000000000000000000000000000000000000000\n"
641+ "parent %s\n"
642+ "author %s\n"
643+ "committer %s\n\n"
644+ "cover letter\n" ,
645+ sha1_to_hex (head -> object .sha1 ), committer , committer );
646+ }
647+
648+ if (!use_stdout && reopen_stdout (commit , rev ))
698649 return ;
699650
700- head_sha1 = sha1_to_hex ( head -> object . sha1 );
651+ if ( commit ) {
701652
702- log_write_email_headers (rev , head_sha1 , & subject_start , & extra_headers ,
703- & need_8bit_cte );
653+ free (commit -> buffer );
654+ free (commit );
655+ }
704656
705- committer = git_committer_info (0 );
657+ log_write_email_headers (rev , head , & subject_start , & extra_headers ,
658+ & need_8bit_cte );
706659
707660 msg = body ;
708661 pp_user_info (NULL , CMIT_FMT_EMAIL , & sb , committer , DATE_RFC2822 ,
@@ -1067,6 +1020,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
10671020 const char * msgid = clean_message_id (in_reply_to );
10681021 string_list_append (msgid , rev .ref_message_ids );
10691022 }
1023+ rev .numbered_files = numbered_files ;
1024+ rev .patch_suffix = fmt_patch_suffix ;
10701025 if (cover_letter ) {
10711026 if (thread )
10721027 gen_message_id (& rev , "cover" );
@@ -1115,9 +1070,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
11151070 }
11161071 gen_message_id (& rev , sha1_to_hex (commit -> object .sha1 ));
11171072 }
1118- if (! use_stdout && reopen_stdout ( numbered_files ? NULL :
1119- get_oneline_for_filename ( commit , keep_subject ) ,
1120- rev . nr , & rev ))
1073+
1074+ if (! use_stdout && reopen_stdout ( numbered_files ? NULL : commit ,
1075+ & rev ))
11211076 die ("Failed to create output files" );
11221077 shown = log_tree_commit (& rev , commit );
11231078 free (commit -> buffer );
0 commit comments