ref-filter: add support to display trailers as part of contents
Add %(trailers) and %(contents:trailers) to display the trailers as interpreted by trailer_info_get. Update documentation and add a test for the new feature. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jacob Keller committed
Nov 18, 2016 at 16:58 UTC
b1d31c8954f9c21b275f4fb7d872414b564c201c
3 files changed
+49
-1
Documentation/git-for-each-ref.txt
+2
@@ -165,6 +165,8 @@ of all lines of the commit message up to the first blank line. The next
165
line is 'contents:body', where body is all of the lines after the first
166
blank line. The optional GPG signature is `contents:signature`. The
167
first `N` lines of the message is obtained using `contents:lines=N`.
168
+Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1]
169
+are obtained as 'contents:trailers'.
170
171
For sorting purposes, fields with numeric values sort in numeric order
172
(`objectsize`, `authordate`, `committerdate`, `creatordate`, `taggerdate`).
ref-filter.c
+21
-1
@@ -13,6 +13,7 @@
13
#include "utf8.h"
14
#include "git-compat-util.h"
15
#include "version.h"
16
+#include "trailer.h"
17
18
typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
19
@@ -40,7 +41,7 @@ static struct used_atom {
41
enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }
42
remote_ref;
43
struct {
43
- enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB } option;
44
+ enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
45
unsigned int nlines;
46
} contents;
47
enum { O_FULL, O_SHORT } objectname;
@@ -85,6 +86,13 @@ static void subject_atom_parser(struct used_atom *atom, const char *arg)
86
atom->u.contents.option = C_SUB;
87
}
88
89
+static void trailers_atom_parser(struct used_atom *atom, const char *arg)
90
+{
91
+ if (arg)
92
+ die(_("%%(trailers) does not take arguments"));
93
+ atom->u.contents.option = C_TRAILERS;
94
+}
95
+
96
static void contents_atom_parser(struct used_atom *atom, const char *arg)
97
{
98
if (!arg)
@@ -95,6 +103,8 @@ static void contents_atom_parser(struct used_atom *atom, const char *arg)
103
atom->u.contents.option = C_SIG;
104
else if (!strcmp(arg, "subject"))
105
atom->u.contents.option = C_SUB;
106
+ else if (!strcmp(arg, "trailers"))
107
+ atom->u.contents.option = C_TRAILERS;
108
else if (skip_prefix(arg, "lines=", &arg)) {
109
atom->u.contents.option = C_LINES;
110
if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
@@ -194,6 +204,7 @@ static struct {
204
{ "creatordate", FIELD_TIME },
205
{ "subject", FIELD_STR, subject_atom_parser },
206
{ "body", FIELD_STR, body_atom_parser },
207
+ { "trailers", FIELD_STR, trailers_atom_parser },
208
{ "contents", FIELD_STR, contents_atom_parser },
209
{ "upstream", FIELD_STR, remote_ref_atom_parser },
210
{ "push", FIELD_STR, remote_ref_atom_parser },
@@ -785,6 +796,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
796
name++;
797
if (strcmp(name, "subject") &&
798
strcmp(name, "body") &&
799
+ strcmp(name, "trailers") &&
800
!starts_with(name, "contents"))
801
continue;
802
if (!subpos)
@@ -808,6 +820,14 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
820
/* Size is the length of the message after removing the signature */
821
append_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);
822
v->s = strbuf_detach(&s, NULL);
823
+ } else if (atom->u.contents.option == C_TRAILERS) {
824
+ struct trailer_info info;
825
+
826
+ /* Search for trailer info */
827
+ trailer_info_get(&info, subpos);
828
+ v->s = xmemdupz(info.trailer_start,
829
+ info.trailer_end - info.trailer_start);
830
+ trailer_info_release(&info);
831
} else if (atom->u.contents.option == C_BARE)
832
v->s = xstrdup(subpos);
833
}
t/t6300-for-each-ref.sh
+26
@@ -553,4 +553,30 @@ test_expect_success 'Verify sort with multiple keys' '
553
refs/tags/bogo refs/tags/master > actual &&
554
test_cmp expected actual
555
'
556
+
557
+cat >trailers <<EOF
558
+Reviewed-by: A U Thor <author@example.com>
559
+Signed-off-by: A U Thor <author@example.com>
560
+EOF
561
+
562
+test_expect_success 'basic atom: head contents:trailers' '
563
+ echo "Some contents" > two &&
564
+ git add two &&
565
+ git commit -F - <<-EOF &&
566
+ trailers: this commit message has trailers
567
+
568
+ Some message contents
569
+
570
+ $(cat trailers)
571
+ EOF
572
+ git for-each-ref --format="%(contents:trailers)" refs/heads/master >actual &&
573
+ sanitize_pgp <actual >actual.clean &&
574
+ # git for-each-ref ends with a blank line
575
+ cat >expect <<-EOF &&
576
+ $(cat trailers)
577
+
578
+ EOF
579
+ test_cmp expect actual.clean
580
+'
581
+
582
test_done