diff mbox series

[v2] format-patch: allow --rfc to optionally take a value, like --rfc=WIP

Message ID xmqqy1993tc1.fsf@gitster.g (mailing list archive)
State New
Headers show
Series [v2] format-patch: allow --rfc to optionally take a value, like --rfc=WIP | expand

Commit Message

Junio C Hamano April 19, 2024, 10:01 p.m. UTC
With the "--rfc" option, we can tweak the "[PATCH]" (or whatever
string specified with the "--subject-prefix" option, instead of
"PATCH") that we prefix the title of the commit with into "[RFC
PATCH]", but some projects may want "[rfc PATCH]".  Adding a new
option, e.g., "--rfc-lowercase", to support such need every time
somebody wants to use different strings would lead to insanity of
accumulating unbounded number of such options.

Allow an optional value specified for the option, so that users can
use "--rfc=rfc" (think of "--rfc" without value as a short-hand for
"--rfc=RFC") if they wanted to.

This can of course be (ab)used to make the prefix "[WIP PATCH]" by
passing "--rfc=WIP".  Passing an empty string, i.e., "--rfc=", is
the same as "--no-rfc" to override an option given earlier on the
same command line.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Range-diff against v1:
1:  4077ed52e8 ! 1:  bffe0055d0 format-patch: allow --rfc to optionally take a value, like --rfc=WIP
    @@ Commit message
     
         Allow an optional value specified for the option, so that users can
         use "--rfc=rfc" (think of "--rfc" without value as a short-hand for
    -    "--rfc=RFC").
    +    "--rfc=RFC") if they wanted to.
     
         This can of course be (ab)used to make the prefix "[WIP PATCH]" by
    -    passing "--rfc=WIP".
    +    passing "--rfc=WIP".  Passing an empty string, i.e., "--rfc=", is
    +    the same as "--no-rfc" to override an option given earlier on the
    +    same command line.
     
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    @@ Documentation/git-format-patch.txt: the patches (with a value of e.g. "PATCH my-
     +RFC means "Request For Comments"; use this when sending
     +an experimental patch for discussion rather than application.
     +"--rfc=WIP" may also be a useful way to indicate that a patch
    -+is not complete yet.
    ++is not complete yet ("WIP" stands for "Work In Progress").
      
      -v <n>::
      --reroll-count=<n>::
    @@ builtin/log.c: static int subject_prefix_callback(const struct option *opt, cons
     +{
     +	struct strbuf *rfc;
     +
    -+	BUG_ON_OPT_NEG(unset);
     +	rfc = opt->value;
     +	strbuf_reset(rfc);
    -+	strbuf_addstr(rfc, arg ? arg : "RFC");
    ++	if (!unset)
    ++		strbuf_addstr(rfc, arg ? arg : "RFC");
     +	return 0;
     +}
     +
    @@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *pre
      		OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
      			    N_("max length of output filename")),
     -		OPT_BOOL(0, "rfc", &rfc, N_("use [RFC PATCH] instead of [PATCH]")),
    -+		OPT_CALLBACK_F(0, "rfc", &rfc, N_("extra"),
    -+			       N_("add <extra> (default 'RFC') before 'PATCH'"),
    -+			       PARSE_OPT_NONEG|PARSE_OPT_OPTARG, rfc_callback),
    ++		OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"),
    ++			       N_("add <rfc> (default 'RFC') before 'PATCH'"),
    ++			       PARSE_OPT_OPTARG, rfc_callback),
      		OPT_STRING(0, "cover-from-description", &cover_from_description_arg,
      			    N_("cover-from-description-mode"),
      			    N_("generate parts of a cover letter based on a branch's description")),
    @@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *pre
      		strbuf_addf(&sprefix, " v%s", reroll_count);
     
      ## t/t4014-format-patch.sh ##
    -@@ t/t4014-format-patch.sh: test_expect_success '--rfc' '
    +@@ t/t4014-format-patch.sh: test_expect_success 'empty subject prefix does not have extra space' '
      	test_cmp expect actual
      '
      
    -+test_expect_success '--rfc=WIP' '
    +-test_expect_success '--rfc' '
    ++test_expect_success '--rfc and --no-rfc' '
    + 	cat >expect <<-\EOF &&
    + 	Subject: [RFC PATCH 1/1] header with . in it
    + 	EOF
    + 	git format-patch -n -1 --stdout --rfc >patch &&
    + 	grep "^Subject:" patch >actual &&
    +-	test_cmp expect actual
    ++	test_cmp expect actual &&
    ++	git format-patch -n -1 --stdout --rfc --no-rfc >patch &&
    ++	sed -e "s/RFC //" expect >expect-raw &&
    ++	grep "^Subject:" patch >actual &&
    ++	test_cmp expect-raw actual
    ++'
    ++
    ++test_expect_success '--rfc=WIP and --rfc=' '
     +	cat >expect <<-\EOF &&
     +	Subject: [WIP PATCH 1/1] header with . in it
     +	EOF
     +	git format-patch -n -1 --stdout --rfc=WIP >patch &&
     +	grep "^Subject:" patch >actual &&
    -+	test_cmp expect actual
    -+'
    -+
    ++	test_cmp expect actual &&
    ++	git format-patch -n -1 --stdout --rfc --rfc= >patch &&
    ++	sed -e "s/WIP //" expect >expect-raw &&
    ++	grep "^Subject:" patch >actual &&
    ++	test_cmp expect-raw actual
    + '
    + 
      test_expect_success '--rfc does not overwrite prefix' '
    - 	cat >expect <<-\EOF &&
    - 	Subject: [RFC PATCH foobar 1/1] header with . in it

 Documentation/git-format-patch.txt | 15 ++++++++++-----
 builtin/log.c                      | 22 ++++++++++++++++++----
 t/t4014-format-patch.sh            | 21 +++++++++++++++++++--
 3 files changed, 47 insertions(+), 11 deletions(-)

Comments

Phillip Wood April 21, 2024, 3:41 p.m. UTC | #1
Hi Junio

On 19/04/2024 23:01, Junio C Hamano wrote:
> With the "--rfc" option, we can tweak the "[PATCH]" (or whatever
> string specified with the "--subject-prefix" option, instead of
> "PATCH") that we prefix the title of the commit with into "[RFC
> PATCH]", but some projects may want "[rfc PATCH]".  Adding a new
> option, e.g., "--rfc-lowercase", to support such need every time
> somebody wants to use different strings would lead to insanity of
> accumulating unbounded number of such options.
> 
> Allow an optional value specified for the option, so that users can
> use "--rfc=rfc" (think of "--rfc" without value as a short-hand for
> "--rfc=RFC") if they wanted to.
> 
> This can of course be (ab)used to make the prefix "[WIP PATCH]" by
> passing "--rfc=WIP".  Passing an empty string, i.e., "--rfc=", is
> the same as "--no-rfc" to override an option given earlier on the
> same command line.

The changes in this version all look good to me, I've left one comment 
below.

> @@ -1907,8 +1919,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
>   	struct strbuf rdiff2 = STRBUF_INIT;
>   	struct strbuf rdiff_title = STRBUF_INIT;
>   	struct strbuf sprefix = STRBUF_INIT;
> +	struct strbuf rfc = STRBUF_INIT;

Looking at this again, do we really need an strbuf here? I think we 
could we use "const char *" instead as we always store a static string 
in it which would avoid a memory leak from not calling strbuf_release().

Best Wishes

Phillip
Junio C Hamano April 21, 2024, 6:58 p.m. UTC | #2
Phillip Wood <phillip.wood123@gmail.com> writes:

>> +	struct strbuf rfc = STRBUF_INIT;
>
> Looking at this again, do we really need an strbuf here? I think we
> could we use "const char *" instead as we always store a static string
> in it which would avoid a memory leak from not calling
> strbuf_release().

Thanks for spotting the leak ;-)

And indeed, unlike sprefix, we do not need it to be an editable
strbuf.

Should be sufficient to squash in something like this.

 builtin/log.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git c/builtin/log.c w/builtin/log.c
index 0e9c84e51d..5c1c6f9b15 100644
--- c/builtin/log.c
+++ w/builtin/log.c
@@ -1497,12 +1497,11 @@ static int subject_prefix_callback(const struct option *opt, const char *arg,
 static int rfc_callback(const struct option *opt, const char *arg,
 			int unset)
 {
-	struct strbuf *rfc;
+	const char **rfc = opt->value;
 
-	rfc = opt->value;
-	strbuf_reset(rfc);
+	*rfc = opt->value;
 	if (!unset)
-		strbuf_addstr(rfc, arg ? arg : "RFC");
+		*rfc = arg ? arg : "RFC";
 	return 0;
 }
 
@@ -1919,7 +1918,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	struct strbuf rdiff2 = STRBUF_INIT;
 	struct strbuf rdiff_title = STRBUF_INIT;
 	struct strbuf sprefix = STRBUF_INIT;
-	struct strbuf rfc = STRBUF_INIT;
+	const char *rfc = NULL;
 	int creation_factor = -1;
 
 	const struct option builtin_format_patch_options[] = {
@@ -2064,8 +2063,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	if (cover_from_description_arg)
 		cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
 
-	if (rfc.len)
-		strbuf_insertf(&sprefix, 0, "%s ", rfc.buf);
+	if (rfc)
+		strbuf_insertf(&sprefix, 0, "%s ", rfc);
 
 	if (reroll_count) {
 		strbuf_addf(&sprefix, " v%s", reroll_count);
diff mbox series

Patch

diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index 728bb3821c..e553810b1e 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -20,7 +20,7 @@  SYNOPSIS
 		   [--in-reply-to=<message-id>] [--suffix=.<sfx>]
 		   [--ignore-if-in-upstream] [--always]
 		   [--cover-from-description=<mode>]
-		   [--rfc] [--subject-prefix=<subject-prefix>]
+		   [--rfc[=<rfc>]] [--subject-prefix=<subject-prefix>]
 		   [(--reroll-count|-v) <n>]
 		   [--to=<email>] [--cc=<email>]
 		   [--[no-]cover-letter] [--quiet]
@@ -238,10 +238,15 @@  the patches (with a value of e.g. "PATCH my-project").
 	value of the `format.filenameMaxLength` configuration
 	variable, or 64 if unconfigured.
 
---rfc::
-	Prepends "RFC" to the subject prefix (producing "RFC PATCH" by
-	default). RFC means "Request For Comments"; use this when sending
-	an experimental patch for discussion rather than application.
+--rfc[=<rfc>]::
+	Prepends the string _<rfc>_ (defaults to "RFC") to
+	the subject prefix.  As the subject prefix defaults to
+	"PATCH", you'll get "RFC PATCH" by default.
++
+RFC means "Request For Comments"; use this when sending
+an experimental patch for discussion rather than application.
+"--rfc=WIP" may also be a useful way to indicate that a patch
+is not complete yet ("WIP" stands for "Work In Progress").
 
 -v <n>::
 --reroll-count=<n>::
diff --git a/builtin/log.c b/builtin/log.c
index c0a8bb95e9..0e9c84e51d 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1494,6 +1494,18 @@  static int subject_prefix_callback(const struct option *opt, const char *arg,
 	return 0;
 }
 
+static int rfc_callback(const struct option *opt, const char *arg,
+			int unset)
+{
+	struct strbuf *rfc;
+
+	rfc = opt->value;
+	strbuf_reset(rfc);
+	if (!unset)
+		strbuf_addstr(rfc, arg ? arg : "RFC");
+	return 0;
+}
+
 static int numbered_cmdline_opt = 0;
 
 static int numbered_callback(const struct option *opt, const char *arg,
@@ -1907,8 +1919,8 @@  int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	struct strbuf rdiff2 = STRBUF_INIT;
 	struct strbuf rdiff_title = STRBUF_INIT;
 	struct strbuf sprefix = STRBUF_INIT;
+	struct strbuf rfc = STRBUF_INIT;
 	int creation_factor = -1;
-	int rfc = 0;
 
 	const struct option builtin_format_patch_options[] = {
 		OPT_CALLBACK_F('n', "numbered", &numbered, NULL,
@@ -1932,7 +1944,9 @@  int cmd_format_patch(int argc, const char **argv, const char *prefix)
 			    N_("mark the series as Nth re-roll")),
 		OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
 			    N_("max length of output filename")),
-		OPT_BOOL(0, "rfc", &rfc, N_("use [RFC PATCH] instead of [PATCH]")),
+		OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"),
+			       N_("add <rfc> (default 'RFC') before 'PATCH'"),
+			       PARSE_OPT_OPTARG, rfc_callback),
 		OPT_STRING(0, "cover-from-description", &cover_from_description_arg,
 			    N_("cover-from-description-mode"),
 			    N_("generate parts of a cover letter based on a branch's description")),
@@ -2050,8 +2064,8 @@  int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	if (cover_from_description_arg)
 		cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
 
-	if (rfc)
-		strbuf_insertstr(&sprefix, 0, "RFC ");
+	if (rfc.len)
+		strbuf_insertf(&sprefix, 0, "%s ", rfc.buf);
 
 	if (reroll_count) {
 		strbuf_addf(&sprefix, " v%s", reroll_count);
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index e37a1411ee..645c4189f9 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1368,13 +1368,30 @@  test_expect_success 'empty subject prefix does not have extra space' '
 	test_cmp expect actual
 '
 
-test_expect_success '--rfc' '
+test_expect_success '--rfc and --no-rfc' '
 	cat >expect <<-\EOF &&
 	Subject: [RFC PATCH 1/1] header with . in it
 	EOF
 	git format-patch -n -1 --stdout --rfc >patch &&
 	grep "^Subject:" patch >actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	git format-patch -n -1 --stdout --rfc --no-rfc >patch &&
+	sed -e "s/RFC //" expect >expect-raw &&
+	grep "^Subject:" patch >actual &&
+	test_cmp expect-raw actual
+'
+
+test_expect_success '--rfc=WIP and --rfc=' '
+	cat >expect <<-\EOF &&
+	Subject: [WIP PATCH 1/1] header with . in it
+	EOF
+	git format-patch -n -1 --stdout --rfc=WIP >patch &&
+	grep "^Subject:" patch >actual &&
+	test_cmp expect actual &&
+	git format-patch -n -1 --stdout --rfc --rfc= >patch &&
+	sed -e "s/WIP //" expect >expect-raw &&
+	grep "^Subject:" patch >actual &&
+	test_cmp expect-raw actual
 '
 
 test_expect_success '--rfc does not overwrite prefix' '