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

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>

Junio C Hamano committed Apr 23, 2024 at 10:52 UTC ce48fb2eabccc269443f33d0f148d0061b94a101
3 files changed +48 -11
Documentation/git-format-patch.txt
+10 -5
@@ -20,7 +20,7 @@ SYNOPSIS
20 [--in-reply-to=<message-id>] [--suffix=.<sfx>]
21 [--ignore-if-in-upstream] [--always]
22 [--cover-from-description=<mode>]
23 - [--rfc] [--subject-prefix=<subject-prefix>]
23 + [--rfc[=<rfc>]] [--subject-prefix=<subject-prefix>]
24 [(--reroll-count|-v) <n>]
25 [--to=<email>] [--cc=<email>]
26 [--[no-]cover-letter] [--quiet]
@@ -238,10 +238,15 @@ the patches (with a value of e.g. "PATCH my-project").
238 value of the `format.filenameMaxLength` configuration
239 variable, or 64 if unconfigured.
240
241 ---rfc::
242 - Prepends "RFC" to the subject prefix (producing "RFC PATCH" by
243 - default). RFC means "Request For Comments"; use this when sending
244 - an experimental patch for discussion rather than application.
241 +--rfc[=<rfc>]::
242 + Prepends the string _<rfc>_ (defaults to "RFC") to
243 + the subject prefix. As the subject prefix defaults to
244 + "PATCH", you'll get "RFC PATCH" by default.
245 ++
246 +RFC means "Request For Comments"; use this when sending
247 +an experimental patch for discussion rather than application.
248 +"--rfc=WIP" may also be a useful way to indicate that a patch
249 +is not complete yet ("WIP" stands for "Work In Progress").
250
251 -v <n>::
252 --reroll-count=<n>::
builtin/log.c
+19 -4
@@ -1494,6 +1494,19 @@ static int subject_prefix_callback(const struct option *opt, const char *arg,
1494 return 0;
1495 }
1496
1497 +static int rfc_callback(const struct option *opt, const char *arg,
1498 + int unset)
1499 +{
1500 + const char **rfc = opt->value;
1501 +
1502 + *rfc = opt->value;
1503 + if (unset)
1504 + *rfc = NULL;
1505 + else
1506 + *rfc = arg ? arg : "RFC";
1507 + return 0;
1508 +}
1509 +
1510 static int numbered_cmdline_opt = 0;
1511
1512 static int numbered_callback(const struct option *opt, const char *arg,
@@ -1907,8 +1920,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1920 struct strbuf rdiff2 = STRBUF_INIT;
1921 struct strbuf rdiff_title = STRBUF_INIT;
1922 struct strbuf sprefix = STRBUF_INIT;
1923 + const char *rfc = NULL;
1924 int creation_factor = -1;
1911 - int rfc = 0;
1925
1926 const struct option builtin_format_patch_options[] = {
1927 OPT_CALLBACK_F('n', "numbered", &numbered, NULL,
@@ -1932,7 +1945,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1945 N_("mark the series as Nth re-roll")),
1946 OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
1947 N_("max length of output filename")),
1935 - OPT_BOOL(0, "rfc", &rfc, N_("use [RFC PATCH] instead of [PATCH]")),
1948 + OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"),
1949 + N_("add <rfc> (default 'RFC') before 'PATCH'"),
1950 + PARSE_OPT_OPTARG, rfc_callback),
1951 OPT_STRING(0, "cover-from-description", &cover_from_description_arg,
1952 N_("cover-from-description-mode"),
1953 N_("generate parts of a cover letter based on a branch's description")),
@@ -2050,8 +2065,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2065 if (cover_from_description_arg)
2066 cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
2067
2053 - if (rfc)
2054 - strbuf_insertstr(&sprefix, 0, "RFC ");
2068 + if (rfc && rfc[0])
2069 + strbuf_insertf(&sprefix, 0, "%s ", rfc);
2070
2071 if (reroll_count) {
2072 strbuf_addf(&sprefix, " v%s", reroll_count);
t/t4014-format-patch.sh
+19 -2
@@ -1368,13 +1368,30 @@ test_expect_success 'empty subject prefix does not have extra space' '
1368 test_cmp expect actual
1369 '
1370
1371 -test_expect_success '--rfc' '
1371 +test_expect_success '--rfc and --no-rfc' '
1372 cat >expect <<-\EOF &&
1373 Subject: [RFC PATCH 1/1] header with . in it
1374 EOF
1375 git format-patch -n -1 --stdout --rfc >patch &&
1376 grep "^Subject:" patch >actual &&
1377 - test_cmp expect actual
1377 + test_cmp expect actual &&
1378 + git format-patch -n -1 --stdout --rfc --no-rfc >patch &&
1379 + sed -e "s/RFC //" expect >expect-raw &&
1380 + grep "^Subject:" patch >actual &&
1381 + test_cmp expect-raw actual
1382 +'
1383 +
1384 +test_expect_success '--rfc=WIP and --rfc=' '
1385 + cat >expect <<-\EOF &&
1386 + Subject: [WIP PATCH 1/1] header with . in it
1387 + EOF
1388 + git format-patch -n -1 --stdout --rfc=WIP >patch &&
1389 + grep "^Subject:" patch >actual &&
1390 + test_cmp expect actual &&
1391 + git format-patch -n -1 --stdout --rfc --rfc= >patch &&
1392 + sed -e "s/WIP //" expect >expect-raw &&
1393 + grep "^Subject:" patch >actual &&
1394 + test_cmp expect-raw actual
1395 '
1396
1397 test_expect_success '--rfc does not overwrite prefix' '