t5573, t7612: clean up after unexpected success of 'pull' and 'merge'
[gitweb.git] / ref-filter.c
index 2259563e732d27b91c1e8515958db2452ba27032..3f9161707e66be86eabaf7347da23a2450ffdd9f 100644 (file)
@@ -84,6 +84,7 @@ static struct used_atom {
                } remote_ref;
                struct {
                        enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
+                       struct process_trailer_options trailer_opts;
                        unsigned int nlines;
                } contents;
                struct {
@@ -193,9 +194,23 @@ static void subject_atom_parser(const struct ref_format *format, struct used_ato
 
 static void trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
 {
-       if (arg)
-               die(_("%%(trailers) does not take arguments"));
+       struct string_list params = STRING_LIST_INIT_DUP;
+       int i;
+
+       if (arg) {
+               string_list_split(&params, arg, ',', -1);
+               for (i = 0; i < params.nr; i++) {
+                       const char *s = params.items[i].string;
+                       if (!strcmp(s, "unfold"))
+                               atom->u.contents.trailer_opts.unfold = 1;
+                       else if (!strcmp(s, "only"))
+                               atom->u.contents.trailer_opts.only_trailers = 1;
+                       else
+                               die(_("unknown %%(trailers) argument: %s"), s);
+               }
+       }
        atom->u.contents.option = C_TRAILERS;
+       string_list_clear(&params, 0);
 }
 
 static void contents_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
@@ -208,9 +223,10 @@ static void contents_atom_parser(const struct ref_format *format, struct used_at
                atom->u.contents.option = C_SIG;
        else if (!strcmp(arg, "subject"))
                atom->u.contents.option = C_SUB;
-       else if (!strcmp(arg, "trailers"))
-               atom->u.contents.option = C_TRAILERS;
-       else if (skip_prefix(arg, "lines=", &arg)) {
+       else if (skip_prefix(arg, "trailers", &arg)) {
+               skip_prefix(arg, ":", &arg);
+               trailers_atom_parser(format, atom, *arg ? arg : NULL);
+       } else if (skip_prefix(arg, "lines=", &arg)) {
                atom->u.contents.option = C_LINES;
                if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
                        die(_("positive value expected contents:lines=%s"), arg);
@@ -424,8 +440,16 @@ static int parse_ref_filter_atom(const struct ref_format *format,
        REALLOC_ARRAY(used_atom, used_atom_cnt);
        used_atom[at].name = xmemdupz(atom, ep - atom);
        used_atom[at].type = valid_atom[i].cmp_type;
-       if (arg)
+       if (arg) {
                arg = used_atom[at].name + (arg - atom) + 1;
+               if (!*arg) {
+                       /*
+                        * Treat empty sub-arguments list as NULL (i.e.,
+                        * "%(atom:)" is equivalent to "%(atom)").
+                        */
+                       arg = NULL;
+               }
+       }
        memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
        if (valid_atom[i].parser)
                valid_atom[i].parser(format, &used_atom[at], arg);
@@ -1051,7 +1075,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
                        name++;
                if (strcmp(name, "subject") &&
                    strcmp(name, "body") &&
-                   strcmp(name, "trailers") &&
+                   !starts_with(name, "trailers") &&
                    !starts_with(name, "contents"))
                        continue;
                if (!subpos)
@@ -1076,13 +1100,12 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
                        append_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);
                        v->s = strbuf_detach(&s, NULL);
                } else if (atom->u.contents.option == C_TRAILERS) {
-                       struct trailer_info info;
+                       struct strbuf s = STRBUF_INIT;
 
-                       /* Search for trailer info */
-                       trailer_info_get(&info, subpos);
-                       v->s = xmemdupz(info.trailer_start,
-                                       info.trailer_end - info.trailer_start);
-                       trailer_info_release(&info);
+                       /* Format the trailer info according to the trailer_opts given */
+                       format_trailers_from_commit(&s, subpos, &atom->u.contents.trailer_opts);
+
+                       v->s = strbuf_detach(&s, NULL);
                } else if (atom->u.contents.option == C_BARE)
                        v->s = xstrdup(subpos);
        }