We used to populate the subject of the cover letter generated by git-format-patch with "*** SUBJECT HERE ***". However, if a user submits multiple patchsets, they may want to keep a consistent subject between rerolls. If git-format-patch is run on a branch that has `branch.<name>.coverSubject` defined, make the cover letter's subject be that value instead of the generic "*** SUBJECT HERE ***". In addition, add the `--cover-subject` option to override this setting. Signed-off-by: Denton Liu <liu.denton@xxxxxxxxx> --- Documentation/config/branch.txt | 4 ++++ Documentation/git-format-patch.txt | 12 ++++++++++++ branch.c | 5 +++++ branch.h | 5 +++++ builtin/log.c | 26 +++++++++++++++++++------- t/t4014-format-patch.sh | 20 ++++++++++++++++++++ t/t9902-completion.sh | 5 ++++- 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt index 019d60ede2..2bff738982 100644 --- a/Documentation/config/branch.txt +++ b/Documentation/config/branch.txt @@ -100,3 +100,7 @@ branch.<name>.description:: `git branch --edit-description`. Branch description is automatically added in the format-patch cover letter or request-pull summary. + +branch.<name>.coverSubject:: + When format-patch generates a cover letter, use the specified + subject for the cover letter instead of the generic template. diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 7b71d4e2ed..af7883acbe 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -19,6 +19,7 @@ SYNOPSIS [--start-number <n>] [--numbered-files] [--in-reply-to=<Message-Id>] [--suffix=.<sfx>] [--ignore-if-in-upstream] + [--cover-subject=<subject>] [--rfc] [--subject-prefix=<Subject-Prefix>] [(--reroll-count|-v) <n>] [--to=<email>] [--cc=<email>] @@ -170,6 +171,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored. +--cover-subject=<subject>:: + Instead of using the default "*** SUBJECT HERE ***" subject for + the cover letter, use the given <subject>. + --subject-prefix=<Subject-Prefix>:: Instead of the standard '[PATCH]' prefix in the subject line, instead use '[<Subject-Prefix>]'. This @@ -346,6 +351,13 @@ attachments, and sign off patches with configuration variables. coverletter = auto ------------ +In addition, for a specific branch, you can specify a custom cover +letter subject. + +------------ +[branch "branch-name"] + coverSubject = "subject for branch-name only" +------------ DISCUSSION ---------- diff --git a/branch.c b/branch.c index 4b49976924..40d30b8fa7 100644 --- a/branch.c +++ b/branch.c @@ -182,6 +182,11 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name) return read_branch_config(buf, branch_name, "description"); } +int read_branch_subject(struct strbuf *buf, const char *branch_name) +{ + return read_branch_config(buf, branch_name, "coversubject"); +} + /* * Check if 'name' can be a valid name for a branch; die otherwise. * Return 1 if the named branch already exists; return 0 otherwise. diff --git a/branch.h b/branch.h index 29c1afa4d0..6a8936bbc8 100644 --- a/branch.h +++ b/branch.h @@ -79,6 +79,11 @@ extern int install_branch_config(int flag, const char *local, const char *origin */ extern int read_branch_desc(struct strbuf *, const char *branch_name); +/* + * Read branch subject + */ +extern int read_branch_subject(struct strbuf *, const char *branch_name); + /* * Check if a branch is checked out in the main worktree or any linked * worktree and die (with a message describing its checkout location) if diff --git a/builtin/log.c b/builtin/log.c index ab859f5904..6f19326aea 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -1034,13 +1034,14 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, struct commit *origin, int nr, struct commit **list, const char *branch_name, + const char *subject, int quiet) { const char *committer; - const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n"; - const char *msg; + const char *body = "*** BLURB HERE ***"; struct shortlog log; struct strbuf sb = STRBUF_INIT; + struct strbuf subject_sb = STRBUF_INIT; int i; const char *encoding = "UTF-8"; int need_8bit_cte = 0; @@ -1068,17 +1069,24 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, if (!branch_name) branch_name = find_branch_name(rev); - msg = body; + if (!subject) { + if (branch_name && *branch_name && !read_branch_subject(&subject_sb, branch_name)) + subject = subject_sb.buf; + else + subject = "*** SUBJECT HERE ***"; + } + pp.fmt = CMIT_FMT_EMAIL; pp.date_mode.type = DATE_RFC2822; pp.rev = rev; pp.print_email_subject = 1; pp_user_info(&pp, NULL, &sb, committer, encoding); - pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte); - pp_remainder(&pp, &msg, &sb, 0); + pp_title_line(&pp, &subject, &sb, encoding, need_8bit_cte); + pp_remainder(&pp, &body, &sb, 0); add_branch_description(&sb, branch_name); fprintf(rev->diffopt.file, "%s\n", sb.buf); + strbuf_release(&subject_sb); strbuf_release(&sb); shortlog_init(&log); @@ -1512,6 +1520,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) int no_binary_diff = 0; int zero_commit = 0; struct commit *origin = NULL; + const char *cover_subject = NULL; const char *in_reply_to = NULL; struct patch_ids ids; struct strbuf buf = STRBUF_INIT; @@ -1554,6 +1563,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) { OPTION_CALLBACK, 0, "rfc", &rev, NULL, N_("Use [RFC PATCH] instead of [PATCH]"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback }, + OPT_STRING(0, "cover-subject", &cover_subject, N_("subject"), + N_("the subject for the cover letter")), { OPTION_CALLBACK, 0, "subject-prefix", &rev, N_("prefix"), N_("Use [<prefix>] instead of [PATCH]"), PARSE_OPT_NONEG, subject_prefix_callback }, @@ -1617,8 +1628,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) extra_to.strdup_strings = 1; extra_cc.strdup_strings = 1; init_log_defaults(); - git_config(git_format_config, NULL); repo_init_revisions(the_repository, &rev, prefix); + + git_config(git_format_config, NULL); rev.commit_format = CMIT_FMT_EMAIL; rev.expand_tabs_in_log_default = 0; rev.verbose_header = 1; @@ -1893,7 +1905,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, - origin, nr, list, branch_name, quiet); + origin, nr, list, branch_name, cover_subject, quiet); print_bases(&bases, rev.diffopt.file); print_signature(rev.diffopt.file); total++; diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index d05cd256c7..1cf4dfbce2 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1463,6 +1463,26 @@ test_expect_success 'format patch ignores color.ui' ' test_cmp expect actual ' +test_expect_success 'cover letter with config subject' ' + test_config branch.rebuild-1.coverSubject "config subject" && + git checkout rebuild-1 && + git format-patch --stdout --cover-letter master >actual && + grep "Subject: \[PATCH 0/2\] config subject" actual +' + +test_expect_success 'cover letter with command-line subject' ' + git checkout rebuild-1 && + git format-patch --stdout --cover-letter --cover-subject "command-line subject" master >actual && + grep "Subject: \[PATCH 0/2\] command-line subject" actual +' + +test_expect_success 'cover letter with command-line subject overrides config' ' + test_config branch.rebuild-1.coverSubject "config subject" && + git checkout rebuild-1 && + git format-patch --stdout --cover-letter --cover-subject "command-line subject" master >actual && + grep "Subject: \[PATCH 0/2\] command-line subject" actual +' + test_expect_success 'cover letter using branch description (1)' ' git checkout rebuild-1 && test_config branch.rebuild-1.description hello && diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index f5e21bf970..0da92179da 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1542,7 +1542,10 @@ test_expect_success 'complete tree filename with metacharacters' ' ' test_expect_success PERL 'send-email' ' - test_completion "git send-email --cov" "--cover-letter " && + test_completion "git send-email --cov" <<-\EOF && + --cover-letter Z + --cover-subject=Z + EOF test_completion "git send-email ma" "master " ' -- 2.21.0.1049.geb646f7864