{"thread":{"id":"59454","subject":"[PATCH] format-patch: add --description-file option","startedAt":"2023-03-23T16:47:47Z","lastAt":"2023-04-27T08:11:27Z","messageCount":2,"participants":["Oswald Buddenhagen"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"474009","messageId":"20230323162234.995420-1-oswald.buddenhagen@gmx.de","threadId":"59454","inReplyTo":null,"subject":"[PATCH] format-patch: add --description-file option","fromName":"Oswald Buddenhagen","fromEmail":"oswald.buddenhagen@gmx.de","sentAt":"2023-03-23T16:22:34Z","receivedAt":"2023-03-23T16:47:47Z","isPatch":true,"sender":{"key":"oswald.buddenhagen@gmx.de","avatar":"https://avatars.githubusercontent.com/u/812380?v=4"},"body":"When formatting patches from a detached HEAD, there is no branch\ndescription to derive the cover letter from. While with format-patch\none could post-process the generated file (which would be ugly enough),\nscripting that with send-email would be *really* ugly. So add an option\nto feed a description directly.\n\nSigned-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>\n---\n Documentation/git-format-patch.txt |  4 ++++\n builtin/log.c                      | 21 ++++++++++++++++++---\n t/t4014-format-patch.sh            | 12 ++++++++++++\n 3 files changed, 34 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex dfcc7da4c2..d074cce95f 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -216,6 +216,10 @@ is greater than 100 bytes, then the mode will be `message`, otherwise\n If `<mode>` is `none`, both the cover letter subject and body will be\n populated with placeholder text.\n \n+--description-file=<file>::\n+\tUse the contents of <file> instead of the branch's description\n+\tfor generating the cover letter.\n+\n --subject-prefix=<subject prefix>::\n \tInstead of the standard '[PATCH]' prefix in the subject\n \tline, instead use '[<subject prefix>]'. This\ndiff --git a/builtin/log.c b/builtin/log.c\nindex bc204ea76f..3f16379a35 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1230,7 +1230,15 @@ static void show_diffstat(struct rev_info *rev,\n \tfprintf(rev->diffopt.file, \"\\n\");\n }\n \n+static void read_desc_file(struct strbuf *buf, const char *desc_file)\n+{\n+\tif (strbuf_read_file(buf, desc_file, 2000) < 0)\n+\t\tdie_errno(_(\"unable to read branch description file '%s'\"),\n+\t\t\t  desc_file);\n+}\n+\n static void prepare_cover_text(struct pretty_print_context *pp,\n+\t\t\t       const char *description_file,\n \t\t\t       const char *branch_name,\n \t\t\t       struct strbuf *sb,\n \t\t\t       const char *encoding,\n@@ -1244,7 +1252,9 @@ static void prepare_cover_text(struct pretty_print_context *pp,\n \tif (cover_from_description_mode == COVER_FROM_NONE)\n \t\tgoto do_pp;\n \n-\tif (branch_name && *branch_name)\n+\tif (description_file && *description_file)\n+\t\tread_desc_file(&description_sb, description_file);\n+\telse if (branch_name && *branch_name)\n \t\tread_branch_desc(&description_sb, branch_name);\n \tif (!description_sb.len)\n \t\tgoto do_pp;\n@@ -1290,6 +1300,7 @@ static void get_notes_args(struct strvec *arg, struct rev_info *rev)\n static void make_cover_letter(struct rev_info *rev, int use_separate_file,\n \t\t\t      struct commit *origin,\n \t\t\t      int nr, struct commit **list,\n+\t\t\t      const char *description_file,\n \t\t\t      const char *branch_name,\n \t\t\t      int quiet)\n {\n@@ -1328,7 +1339,8 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,\n \tpp.rev = rev;\n \tpp.print_email_subject = 1;\n \tpp_user_info(&pp, NULL, &sb, committer, encoding);\n-\tprepare_cover_text(&pp, branch_name, &sb, encoding, need_8bit_cte);\n+\tprepare_cover_text(&pp, description_file, branch_name, &sb,\n+\t\t\t   encoding, need_8bit_cte);\n \tfprintf(rev->diffopt.file, \"%s\\n\", sb.buf);\n \n \tstrbuf_release(&sb);\n@@ -1865,6 +1877,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tint quiet = 0;\n \tconst char *reroll_count = NULL;\n \tchar *cover_from_description_arg = NULL;\n+\tchar *description_file = NULL;\n \tchar *branch_name = NULL;\n \tchar *base_commit = NULL;\n \tstruct base_tree_info bases;\n@@ -1908,6 +1921,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\tOPT_STRING(0, \"cover-from-description\", &cover_from_description_arg,\n \t\t\t    N_(\"cover-from-description-mode\"),\n \t\t\t    N_(\"generate parts of a cover letter based on a branch's description\")),\n+\t\tOPT_FILENAME(0, \"description-file\", &description_file,\n+\t\t\t     N_(\"use branch description from file\")),\n \t\tOPT_CALLBACK_F(0, \"subject-prefix\", &rev, N_(\"prefix\"),\n \t\t\t    N_(\"use [<prefix>] instead of [PATCH]\"),\n \t\t\t    PARSE_OPT_NONEG, subject_prefix_callback),\n@@ -2290,7 +2305,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\tif (thread)\n \t\t\tgen_message_id(&rev, \"cover\");\n \t\tmake_cover_letter(&rev, !!output_directory,\n-\t\t\t\t  origin, nr, list, branch_name, quiet);\n+\t\t\t\t  origin, nr, list, description_file, branch_name, quiet);\n \t\tprint_bases(&bases, rev.diffopt.file);\n \t\tprint_signature(rev.diffopt.file);\n \t\ttotal++;\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex ffc7c60680..e585ab0b23 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -1986,6 +1986,18 @@ test_expect_success 'cover letter using branch description (6)' '\n \tgrep hello actual\n '\n \n+test_expect_success 'cover letter with --description-file' '\n+\ttest_when_finished \"rm -f description.txt\" &&\n+\techo \"subject from file\n+\n+body from file\" > description.txt &&\n+\tgit checkout rebuild-1 &&\n+\tgit format-patch --stdout --cover-letter --cover-from-description auto \\\n+\t\t--description-file description.txt main >actual &&\n+\tgrep \"^Subject: \\[PATCH 0/2\\] subject from file$\" actual &&\n+\tgrep \"^body from file$\" actual\n+'\n+\n test_expect_success 'cover letter with nothing' '\n \tgit format-patch --stdout --cover-letter >actual &&\n \ttest_line_count = 0 actual\n-- \n2.40.0.152.g15d061e6df\n\n"},{"id":"476176","messageId":"ZEouKn2uPP5FAqj7@ugly","threadId":"59454","inReplyTo":"20230323162234.995420-1-oswald.buddenhagen@gmx.de","subject":"Re: [PATCH] format-patch: add --description-file option","fromName":"Oswald Buddenhagen","fromEmail":"oswald.buddenhagen@gmx.de","sentAt":"2023-04-27T08:11:22Z","receivedAt":"2023-04-27T08:11:27Z","isPatch":true,"sender":{"key":"oswald.buddenhagen@gmx.de","avatar":"https://avatars.githubusercontent.com/u/812380?v=4"},"body":"ping!\n\nOn Thu, Mar 23, 2023 at 05:22:34PM +0100, Oswald Buddenhagen wrote:\n>When formatting patches from a detached HEAD, there is no branch\n>description to derive the cover letter from. While with format-patch\n>one could post-process the generated file (which would be ugly enough),\n>scripting that with send-email would be *really* ugly. So add an option\n>to feed a description directly.\n>\n"}]}