format-patch: refactor get_patch_filename

The get_patch_filename function expects a commit argument and uses it to get the sanitized subject line when making a patch filename. However, we also want to use this same function for the cover letter, which does not have a commit object. The current solution is to create a fake commit with the subject "cover letter". Instead, let's make the get_patch_filename interface more flexibile, and allow passing a direct subject. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 21, 2012 at 19:10 UTC a21c2f94fb6e74ebddb5c78cf6b5f68983646530
3 files changed +20 -38
builtin/log.c
+7 -28
@@ -663,7 +663,8 @@ static FILE *realstdout = NULL;
663 static const char *output_directory = NULL;
664 static int outdir_offset;
665
666 -static int reopen_stdout(struct commit *commit, struct rev_info *rev, int quiet)
666 +static int reopen_stdout(struct commit *commit, const char *subject,
667 + struct rev_info *rev, int quiet)
668 {
669 struct strbuf filename = STRBUF_INIT;
670 int suffix_len = strlen(fmt_patch_suffix) + 1;
@@ -677,7 +678,7 @@ static int reopen_stdout(struct commit *commit, struct rev_info *rev, int quiet)
678 strbuf_addch(&filename, '/');
679 }
680
680 - get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
681 + get_patch_filename(commit, subject, rev->nr, fmt_patch_suffix, &filename);
682
683 if (!quiet)
684 fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
@@ -778,7 +779,6 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
779 const char *encoding = "UTF-8";
780 struct diff_options opts;
781 int need_8bit_cte = 0;
781 - struct commit *commit = NULL;
782 struct pretty_print_context pp = {0};
783
784 if (rev->commit_format != CMIT_FMT_EMAIL)
@@ -786,31 +786,10 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
786
787 committer = git_committer_info(0);
788
789 - if (!numbered_files) {
790 - /*
791 - * We fake a commit for the cover letter so we get the filename
792 - * desired.
793 - */
794 - commit = xcalloc(1, sizeof(*commit));
795 - commit->buffer = xmalloc(400);
796 - snprintf(commit->buffer, 400,
797 - "tree 0000000000000000000000000000000000000000\n"
798 - "parent %s\n"
799 - "author %s\n"
800 - "committer %s\n\n"
801 - "cover letter\n",
802 - sha1_to_hex(head->object.sha1), committer, committer);
803 - }
804 -
805 - if (!use_stdout && reopen_stdout(commit, rev, quiet))
789 + if (!use_stdout &&
790 + reopen_stdout(NULL, numbered_files ? NULL : "cover-letter", rev, quiet))
791 return;
792
808 - if (commit) {
809 -
810 - free(commit->buffer);
811 - free(commit);
812 - }
813 -
793 log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
794 &need_8bit_cte);
795
@@ -1405,8 +1384,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1384 gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
1385 }
1386
1408 - if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
1409 - &rev, quiet))
1387 + if (!use_stdout &&
1388 + reopen_stdout(numbered_files ? NULL : commit, NULL, &rev, quiet))
1389 die(_("Failed to create output files"));
1390 shown = log_tree_commit(&rev, commit);
1391 free(commit->buffer);
log-tree.c
+11 -8
@@ -299,19 +299,22 @@ static unsigned int digits_in_number(unsigned int number)
299 return result;
300 }
301
302 -void get_patch_filename(struct commit *commit, int nr, const char *suffix,
303 - struct strbuf *buf)
302 +void get_patch_filename(struct commit *commit, const char *subject, int nr,
303 + const char *suffix, struct strbuf *buf)
304 {
305 int suffix_len = strlen(suffix) + 1;
306 int start_len = buf->len;
307
308 - strbuf_addf(buf, commit ? "%04d-" : "%d", nr);
309 - if (commit) {
308 + strbuf_addf(buf, commit || subject ? "%04d-" : "%d", nr);
309 + if (commit || subject) {
310 int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
311 struct pretty_print_context ctx = {0};
312 - ctx.date_mode = DATE_NORMAL;
312
314 - format_commit_message(commit, "%f", buf, &ctx);
313 + if (subject)
314 + strbuf_addstr(buf, subject);
315 + else if (commit)
316 + format_commit_message(commit, "%f", buf, &ctx);
317 +
318 if (max_len < buf->len)
319 strbuf_setlen(buf, max_len);
320 strbuf_addstr(buf, suffix);
@@ -384,8 +387,8 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
387 mime_boundary_leader, opt->mime_boundary);
388 extra_headers = subject_buffer;
389
387 - get_patch_filename(opt->numbered_files ? NULL : commit, opt->nr,
388 - opt->patch_suffix, &filename);
390 + get_patch_filename(opt->numbered_files ? NULL : commit, NULL,
391 + opt->nr, opt->patch_suffix, &filename);
392 snprintf(buffer, sizeof(buffer) - 1,
393 "\n--%s%s\n"
394 "Content-Type: text/x-patch;"
log-tree.h
+2 -2
@@ -21,7 +21,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
21 void load_ref_decorations(int flags);
22
23 #define FORMAT_PATCH_NAME_MAX 64
24 -void get_patch_filename(struct commit *commit, int nr, const char *suffix,
25 - struct strbuf *buf);
24 +void get_patch_filename(struct commit *commit, const char *subject, int nr,
25 + const char *suffix, struct strbuf *buf);
26
27 #endif