git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v5 0/3] format-patch: learn --cover-from-description option

From
Denton Liu <liu.denton@gmail.com>
Date
Oct 14, 2019, 20:46 UTC
Message-ID
<cover.1571085952.git.liu.denton@gmail.com>
In-Reply-To
<cover.1570821015.git.liu.denton@gmail.com>

Currently, format-patch only puts "*** SUBJECT HERE ***" when a cover letter is generated. However, it is already smart enough to be able to populate the cover letter with the branch description so there's no reason why it cannot populate the subject as well.

Teach format-patch the `--cover-from-description` option and corresponding `format.coverFromDescription` configuration option which will allow it to populate not only the body but the subject as well.

Changes since v4:
* Modify 1/3 to more closely reflect intent of the original author
* Incorporate Junio's suggestions into the documentation
* Extract branch desc logic into pp_from_desc()
* Fix broken tests
Changes since v3:
* Change --infer-cover-subject to --cover-from-description
* No more test cleanup patches (they were merged in
  'dl/format-patch-doc-test-cleanup')
Changes since v2:
* Break 1/4 into many different patches (one per paragraph of the
  original patch)
* Incorporate Eric's documentation/commit message suggestions
Changes since v1:
* Incorporate Eric's suggestions for cleanup in all patches
* Add patch 3/4 to make it clear what is the default value for
  format.coverLetter (since format.inferCoverSubject was borrowed from
  this config but it also did not state what the default value was)
* In 1/4, rename all instances of "expected" to "expect"
Denton Liu (3):
  format-patch: change erroneous and condition
  format-patch: use enum variables
  format-patch: teach --cover-from-description option
 Documentation/config/format.txt    |   6 +
 Documentation/git-format-patch.txt |  22 ++++
 builtin/log.c                      | 125 +++++++++++++++------
 t/t4014-format-patch.sh            | 172 +++++++++++++++++++++++++++++
 t/t9902-completion.sh              |   5 +-
 5 files changed, 296 insertions(+), 34 deletions(-)
Range-diff against v4:
1:  267bc00dc8 ! 1:  56fb230ad2 format-patch: remove erroneous and condition
    @@ Metadata
     Author: Denton Liu <liu.denton@gmail.com>
     
      ## Commit message ##
    -    format-patch: remove erroneous and condition
    +    format-patch: change erroneous and condition
     
         Commit 30984ed2e9 (format-patch: support deep threading, 2009-02-19),
         introduced the following lines:
    @@ Commit message
                 thread = git_config_bool(var, value) && THREAD_SHALLOW;
     
         Since git_config_bool() returns a bool, the trailing `&& THREAD_SHALLOW`
    -    is a no-op. Remove this erroneous and condition.
    +    is a no-op.
    +
    +    In Python, `x and y` is equivalent to `y if x else x`[1]. Since this
    +    seems to be a Python-ism that's mistakenly leaked into our code, convert
    +    this to the equivalent C expression.
    +
    +    [1]: https://docs.python.org/3/reference/expressions.html#boolean-operations
     
         Signed-off-by: Denton Liu <liu.denton@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      ## builtin/log.c ##
     @@ builtin/log.c: static int git_format_config(const char *var, const char *value, void *cb)
    @@ builtin/log.c: static int git_format_config(const char *var, const char *value,
      			return 0;
      		}
     -		thread = git_config_bool(var, value) && THREAD_SHALLOW;
    -+		thread = git_config_bool(var, value);
    ++		thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET;
      		return 0;
      	}
      	if (!strcmp(var, "format.signoff")) {
2:  638a5b40d2 ! 2:  e2769092fa format-patch: use enum variables
    @@ Commit message
         variables to use these new definitions.
     
         Signed-off-by: Denton Liu <liu.denton@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      ## builtin/log.c ##
     @@ builtin/log.c: static void add_header(const char *value)
3:  3289ce62bb ! 3:  315c308950 format-patch: teach --cover-from-description option
    @@ Commit message
         populate different parts of the cover letter (including the subject
         now).
     
    -    Signed-off-by: Denton Liu <liu.denton@gmail.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    -
      ## Documentation/config/format.txt ##
     @@ Documentation/config/format.txt: format.subjectPrefix::
      	The default for format-patch is to output files with the '[PATCH]'
    @@ Documentation/git-format-patch.txt: will want to ensure that threading is disabl
     ++
     +If `<mode>` is `message` or `default`, the cover letter subject will be
     +populated with placeholder text. The body of the cover letter will be
    -+populated with the branch's description.
    ++populated with the branch's description. This is the default mode when
    ++no configuration nor command line option is specified.
     ++
    -+If `<mode>` is `subject`, the beginning of the branch description (up to
    -+the first blank line) will populate the cover letter subject. The
    -+remainder of the description will populate the body of the cover
    -+letter.
    ++If `<mode>` is `subject`, the first paragraph of the branch description will
    ++populate the cover letter subject. The remainder of the description will
    ++populate the body of the cover letter.
     ++
    -+If `<mode>` is `auto`, if the beginning of the branch description (up to
    -+the first line) is greater than 100 characters then the mode will be
    -+`message`, otherwise `subject` will be used.
    ++If `<mode>` is `auto`, if the first paragraph of the branch description
    ++is greater than 100 bytes, then the mode will be `message`, otherwise
    ++`subject` will be used.
     ++
     +If `<mode>` is `none`, both the cover letter subject and body will be
     +populated with placeholder text.
    @@ builtin/log.c: static void print_signature(FILE *file)
      static char *find_branch_name(struct rev_info *rev)
      {
      	int i, positive = -1;
    -@@ builtin/log.c: static void make_cover_letter(struct rev_info *rev, int use_stdout,
    +@@ builtin/log.c: static void show_diffstat(struct rev_info *rev,
    + 	fprintf(rev->diffopt.file, "\n");
    + }
    + 
    ++static void pp_from_desc(struct pretty_print_context *pp,
    ++			 const char *branch_name,
    ++			 struct strbuf *sb,
    ++			 const char *encoding,
    ++			 int need_8bit_cte)
    ++{
    ++	const char *subject = "*** SUBJECT HERE ***";
    ++	const char *body = "*** BLURB HERE ***";
    ++	struct strbuf description_sb = STRBUF_INIT;
    ++	struct strbuf subject_sb = STRBUF_INIT;
    ++
    ++	if (cover_from_description_mode == COVER_FROM_NONE)
    ++		goto do_pp;
    ++
    ++	if (branch_name && *branch_name)
    ++		read_branch_desc(&description_sb, branch_name);
    ++	if (!description_sb.len)
    ++		goto do_pp;
    ++
    ++	if (cover_from_description_mode == COVER_FROM_SUBJECT ||
    ++			cover_from_description_mode == COVER_FROM_AUTO)
    ++		body = format_subject(&subject_sb, description_sb.buf, " ");
    ++
    ++	if (cover_from_description_mode == COVER_FROM_MESSAGE ||
    ++			(cover_from_description_mode == COVER_FROM_AUTO &&
    ++			 subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN))
    ++		body = description_sb.buf;
    ++	else
    ++		subject = subject_sb.buf;
    ++
    ++do_pp:
    ++	pp_title_line(pp, &subject, sb, encoding, need_8bit_cte);
    ++	pp_remainder(pp, &body, sb, 0);
    ++
    ++	strbuf_release(&description_sb);
    ++	strbuf_release(&subject_sb);
    ++}
    ++
    + static void make_cover_letter(struct rev_info *rev, int use_stdout,
      			      struct commit *origin,
      			      int nr, struct commit **list,
    - 			      const char *branch_name,
    -+			      enum cover_from_description cover_from_description_mode,
    +@@ builtin/log.c: static void make_cover_letter(struct rev_info *rev, int use_stdout,
      			      int quiet)
      {
      	const char *committer;
     -	const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
     -	const char *msg;
    -+	const char *subject = "*** SUBJECT HERE ***";
    -+	const char *body = "*** BLURB HERE ***";
      	struct shortlog log;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct strbuf description_sb = STRBUF_INIT;
    -+	struct strbuf subject_sb = STRBUF_INIT;
      	int i;
    - 	const char *encoding = "UTF-8";
    - 	int need_8bit_cte = 0;
     @@ builtin/log.c: static void make_cover_letter(struct rev_info *rev, int use_stdout,
      	if (!branch_name)
      		branch_name = find_branch_name(rev);
      
     -	msg = body;
    -+	if (branch_name && *branch_name)
    -+		read_branch_desc(&description_sb, branch_name);
    -+
    -+	if (cover_from_description_mode != COVER_FROM_NONE && description_sb.len) {
    -+		if (cover_from_description_mode == COVER_FROM_SUBJECT ||
    -+				cover_from_description_mode == COVER_FROM_AUTO)
    -+			body = format_subject(&subject_sb, description_sb.buf, " ");
    -+
    -+		if (cover_from_description_mode == COVER_FROM_MESSAGE ||
    -+				(cover_from_description_mode == COVER_FROM_AUTO &&
    -+				 subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN))
    -+			body = description_sb.buf;
    -+		else
    -+			subject = subject_sb.buf;
    -+	}
    -+
      	pp.fmt = CMIT_FMT_EMAIL;
      	pp.date_mode.type = DATE_RFC2822;
      	pp.rev = rev;
    @@ builtin/log.c: static void make_cover_letter(struct rev_info *rev, int use_stdou
     -	pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
     -	pp_remainder(&pp, &msg, &sb, 0);
     -	add_branch_description(&sb, branch_name);
    -+	pp_title_line(&pp, &subject, &sb, encoding, need_8bit_cte);
    -+	pp_remainder(&pp, &body, &sb, 0);
    -+	strbuf_addch(&sb, '\n');
    ++	pp_from_desc(&pp, branch_name, &sb, encoding, need_8bit_cte);
      	fprintf(rev->diffopt.file, "%s\n", sb.buf);
      
    -+	strbuf_release(&description_sb);
    -+	strbuf_release(&subject_sb);
      	strbuf_release(&sb);
    - 
    - 	shortlog_init(&log);
     @@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *prefix)
      	int use_patch_format = 0;
      	int quiet = 0;
    @@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *pre
      	if (0 < reroll_count) {
      		struct strbuf sprefix = STRBUF_INIT;
      		strbuf_addf(&sprefix, "%s v%d",
    -@@ builtin/log.c: 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_from_description_mode, quiet);
    - 		print_bases(&bases, rev.diffopt.file);
    - 		print_signature(rev.diffopt.file);
    - 		total++;
     
      ## t/t4014-format-patch.sh ##
     @@ t/t4014-format-patch.sh: test_expect_success 'format patch ignores color.ui' '
    @@ t/t4014-format-patch.sh: test_expect_success 'format patch ignores color.ui' '
      test_expect_success 'cover letter using branch description (1)' '
      	git checkout rebuild-1 &&
      	test_config branch.rebuild-1.description hello &&
    +
    + ## t/t9902-completion.sh ##
    +@@ t/t9902-completion.sh: 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-from-description=Z
    ++	--cover-letter Z
    ++	EOF
    + 	test_completion "git send-email ma" "master "
    + '
    + 
-- 
2.23.0.17.g315c308950
Previous: Junio C HamanoNext: Denton Liu
Message 85 of 91 in “format-patch: learn --infer-cover-subject option”
  1. 0/4 format-patch: learn --infer-cover-subject optionDenton Liu, Aug 19, 2019
  2. 1/4 t4014: clean up styleDenton Liu, Aug 19, 2019
  3. Eric SunshineAug 20, 2019
  4. 2/4 Doc: add more detail for git-format-patchDenton Liu, Aug 19, 2019
  5. Eric SunshineAug 20, 2019
  6. Denton LiuAug 20, 2019
  7. 3/4 config/format.txt: make clear the default value of format.coverLetterDenton Liu, Aug 19, 2019
  8. Eric SunshineAug 20, 2019
  9. 4/4 format-patch: learn --infer-cover-letter optionDenton Liu, Aug 19, 2019
  10. Eric SunshineAug 20, 2019
  11. 00/13 format-patch: learn --infer-cover-subject option (also t4014 cleanup)Denton Liu, Aug 20, 2019
  12. 01/13 t4014: drop unnecessary blank lines from test casesDenton Liu, Aug 20, 2019
  13. 02/13 t4014: s/expected/expect/Denton Liu, Aug 20, 2019
  14. Eric SunshineAug 20, 2019
  15. 03/13 t4014: move closing sq onto its own lineDenton Liu, Aug 20, 2019
  16. 04/13 t4014: use sq for test case namesDenton Liu, Aug 20, 2019
  17. 05/13 t4014: remove spaces after redirect operatorsDenton Liu, Aug 20, 2019
  18. 06/13 t4014: use indentable here-docsDenton Liu, Aug 20, 2019
  19. 07/13 t4014: drop redirections to /dev/nullDenton Liu, Aug 20, 2019
  20. 08/13 t4014: use test_line_count() where possibleDenton Liu, Aug 20, 2019
  21. 09/13 t4014: remove confusing pipe in check_threading()Denton Liu, Aug 20, 2019
  22. 10/13 t4014: stop losing return codes of git commandsDenton Liu, Aug 20, 2019
  23. Denton LiuAug 20, 2019
  24. Johannes SixtAug 20, 2019
  25. 11/13 Doc: add more detail for git-format-patchDenton Liu, Aug 20, 2019
  26. Junio C HamanoAug 21, 2019
  27. 12/13 config/format.txt: specify default value of format.coverLetterDenton Liu, Aug 20, 2019
  28. 13/13 format-patch: learn --infer-cover-subject optionDenton Liu, Aug 20, 2019
  29. Junio C HamanoAug 21, 2019
  30. Denton LiuAug 23, 2019
  31. Philip OakleyAug 23, 2019
  32. Junio C HamanoAug 23, 2019
  33. Denton LiuAug 24, 2019
  34. Philip OakleyAug 24, 2019
  35. Junio C HamanoAug 26, 2019
  36. Junio C HamanoAug 26, 2019
  37. Junio C HamanoAug 26, 2019
  38. Junio C HamanoAug 22, 2019
  39. Denton LiuAug 23, 2019
  40. Junio C HamanoAug 23, 2019
  41. 00/13 format-patch: clean up tests and documentationDenton Liu, Aug 24, 2019
  42. 01/13 t4014: drop unnecessary blank lines from test casesDenton Liu, Aug 24, 2019
  43. 02/13 t4014: s/expected/expect/Denton Liu, Aug 24, 2019
  44. 03/13 t4014: move closing sq onto its own lineDenton Liu, Aug 24, 2019
  45. 04/13 t4014: use sq for test case namesDenton Liu, Aug 24, 2019
  46. 05/13 t4014: remove spaces after redirect operatorsDenton Liu, Aug 24, 2019
  47. 06/13 t4014: use indentable here-docsDenton Liu, Aug 24, 2019
  48. 07/13 t4014: drop redirections to /dev/nullDenton Liu, Aug 24, 2019
  49. 08/13 t4014: let sed open its own filesDenton Liu, Aug 24, 2019
  50. Eric SunshineAug 26, 2019
  51. 09/13 t4014: use test_line_count() where possibleDenton Liu, Aug 24, 2019
  52. 10/13 t4014: remove confusing pipe in check_threading()Denton Liu, Aug 24, 2019
  53. 11/13 t4014: stop losing return codes of git commandsDenton Liu, Aug 24, 2019
  54. 12/13 Doc: add more detail for git-format-patchDenton Liu, Aug 24, 2019
  55. Junio C HamanoAug 26, 2019
  56. Junio C HamanoAug 26, 2019
  57. 13/13 config/format.txt: specify default value of format.coverLetterDenton Liu, Aug 24, 2019
  58. Denton LiuAug 24, 2019
  59. Junio C HamanoAug 26, 2019
  60. 00/13 format-patch: clean up tests and documentationDenton Liu, Aug 27, 2019
  61. 01/13 t4014: drop unnecessary blank lines from test casesDenton Liu, Aug 27, 2019
  62. 02/13 t4014: s/expected/expect/Denton Liu, Aug 27, 2019
  63. 03/13 t4014: move closing sq onto its own lineDenton Liu, Aug 27, 2019
  64. 04/13 t4014: use sq for test case namesDenton Liu, Aug 27, 2019
  65. 05/13 t4014: remove spaces after redirect operatorsDenton Liu, Aug 27, 2019
  66. 06/13 t4014: use indentable here-docsDenton Liu, Aug 27, 2019
  67. 07/13 t4014: drop redirections to /dev/nullDenton Liu, Aug 27, 2019
  68. 08/13 t4014: let sed open its own filesDenton Liu, Aug 27, 2019
  69. 09/13 t4014: use test_line_count() where possibleDenton Liu, Aug 27, 2019
  70. 10/13 t4014: remove confusing pipe in check_threading()Denton Liu, Aug 27, 2019
  71. 11/13 t4014: stop losing return codes of git commandsDenton Liu, Aug 27, 2019
  72. 12/13 Doc: add more detail for git-format-patchDenton Liu, Aug 27, 2019
  73. 13/13 config/format.txt: specify default value of format.coverLetterDenton Liu, Aug 27, 2019
  74. Denton LiuSep 4, 2019
  75. Junio C HamanoSep 5, 2019
  76. Denton LiuSep 5, 2019
  77. 0/3 format-patch: learn --cover-from-description optionDenton Liu, Oct 11, 2019
  78. 1/3 format-patch: remove erroneous and conditionDenton Liu, Oct 11, 2019
  79. 2/3 format-patch: use enum variablesDenton Liu, Oct 11, 2019
  80. Junio C HamanoOct 12, 2019
  81. 3/3 format-patch: teach --cover-from-description optionDenton Liu, Oct 11, 2019
  82. Junio C HamanoOct 12, 2019
  83. 4/3 fixup! format-patch: teach --cover-from-description optionDenton Liu, Oct 11, 2019
  84. Junio C HamanoOct 12, 2019
  85. 0/3 format-patch: learn --cover-from-description optionDenton Liu, Oct 14, 2019
  86. 1/3 format-patch: change erroneous and conditionDenton Liu, Oct 14, 2019
  87. Junio C HamanoOct 15, 2019
  88. Denton LiuOct 15, 2019
  89. 2/3 format-patch: use enum variablesDenton Liu, Oct 14, 2019
  90. 3/3 format-patch: teach --cover-from-description optionDenton Liu, Oct 14, 2019
  91. Junio C HamanoOct 15, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.