pretty: allow %(trailers) options with explicit value

In addition to old %(trailers:only) it is now allowed to write %(trailers:only=yes) By itself this only gives (the not quite so useful) possibility to have users change their mind in the middle of a formatting string (%(trailers:only=true,only=false)). However, it gives users the opportunity to override defaults from future options. Signed-off-by: Anders Waldenborg <anders@0x63.nu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Anders Waldenborg committed Jan 29, 2019 at 07:49 UTC 4f732e0fd7a524759424c817b92848949db1e2db
3 files changed +73 -11
Documentation/pretty-formats.txt
+10 -4
@@ -225,10 +225,16 @@ endif::git-rev-list[]
225 linkgit:git-interpret-trailers[1]. The
226 `trailers` string may be followed by a colon
227 and zero or more comma-separated options:
228 -** 'only': omit non-trailer lines from the trailer block.
229 -** 'unfold': make it behave as if interpret-trailer's `--unfold`
230 - option was given. E.g., `%(trailers:only,unfold)` unfolds and
231 - shows all trailer lines.
228 +** 'only[=val]': select whether non-trailer lines from the trailer
229 + block should be included. The `only` keyword may optionally be
230 + followed by an equal sign and one of `true`, `on`, `yes` to omit or
231 + `false`, `off`, `no` to show the non-trailer lines. If option is
232 + given without value it is enabled. If given multiple times the last
233 + value is used.
234 +** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold`
235 + option was given. In same way as to for `only` it can be followed
236 + by an equal sign and explicit value. E.g.,
237 + `%(trailers:only,unfold=true)` unfolds and shows all trailer lines.
238
239 NOTE: Some placeholders may depend on other options given to the
240 revision traversal engine. For example, the `%g*` reflog options will
pretty.c
+45 -7
@@ -1056,13 +1056,26 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
1056 return 0;
1057 }
1058
1059 -static int match_placeholder_arg(const char *to_parse, const char *candidate,
1060 - const char **end)
1059 +static int match_placeholder_arg_value(const char *to_parse, const char *candidate,
1060 + const char **end, const char **valuestart,
1061 + size_t *valuelen)
1062 {
1063 const char *p;
1064
1065 if (!(skip_prefix(to_parse, candidate, &p)))
1066 return 0;
1067 + if (valuestart) {
1068 + if (*p == '=') {
1069 + *valuestart = p + 1;
1070 + *valuelen = strcspn(*valuestart, ",)");
1071 + p = *valuestart + *valuelen;
1072 + } else {
1073 + if (*p != ',' && *p != ')')
1074 + return 0;
1075 + *valuestart = NULL;
1076 + *valuelen = 0;
1077 + }
1078 + }
1079 if (*p == ',') {
1080 *end = p + 1;
1081 return 1;
@@ -1074,6 +1087,34 @@ static int match_placeholder_arg(const char *to_parse, const char *candidate,
1087 return 0;
1088 }
1089
1090 +static int match_placeholder_bool_arg(const char *to_parse, const char *candidate,
1091 + const char **end, int *val)
1092 +{
1093 + const char *argval;
1094 + char *strval;
1095 + size_t arglen;
1096 + int v;
1097 +
1098 + if (!match_placeholder_arg_value(to_parse, candidate, end, &argval, &arglen))
1099 + return 0;
1100 +
1101 + if (!argval) {
1102 + *val = 1;
1103 + return 1;
1104 + }
1105 +
1106 + strval = xstrndup(argval, arglen);
1107 + v = git_parse_maybe_bool(strval);
1108 + free(strval);
1109 +
1110 + if (v == -1)
1111 + return 0;
1112 +
1113 + *val = v;
1114 +
1115 + return 1;
1116 +}
1117 +
1118 static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1119 const char *placeholder,
1120 void *context)
@@ -1318,11 +1359,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1359 if (*arg == ':') {
1360 arg++;
1361 for (;;) {
1321 - if (match_placeholder_arg(arg, "only", &arg))
1322 - opts.only_trailers = 1;
1323 - else if (match_placeholder_arg(arg, "unfold", &arg))
1324 - opts.unfold = 1;
1325 - else
1362 + if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) &&
1363 + !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold))
1364 break;
1365 }
1366 }
t/t4205-log-pretty-formats.sh
+18
@@ -578,6 +578,24 @@ test_expect_success '%(trailers:only) shows only "key: value" trailers' '
578 test_cmp expect actual
579 '
580
581 +test_expect_success '%(trailers:only=yes) shows only "key: value" trailers' '
582 + git log --no-walk --pretty=format:"%(trailers:only=yes)" >actual &&
583 + grep -v patch.description <trailers >expect &&
584 + test_cmp expect actual
585 +'
586 +
587 +test_expect_success '%(trailers:only=no) shows all trailers' '
588 + git log --no-walk --pretty=format:"%(trailers:only=no)" >actual &&
589 + cat trailers >expect &&
590 + test_cmp expect actual
591 +'
592 +
593 +test_expect_success '%(trailers:only=no,only=true) shows only "key: value" trailers' '
594 + git log --no-walk --pretty=format:"%(trailers:only=yes)" >actual &&
595 + grep -v patch.description <trailers >expect &&
596 + test_cmp expect actual
597 +'
598 +
599 test_expect_success '%(trailers:unfold) unfolds trailers' '
600 git log --no-walk --pretty="%(trailers:unfold)" >actual &&
601 {