Now %(contents:subject) contains the message subject, %(contents:body) main body part and %(contents:signature) GPG signature. --- Documentation/git-for-each-ref.txt | 7 +++-- builtin/for-each-ref.c | 42 ++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 152e695..c872b88 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -101,9 +101,10 @@ Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, and `date` to extract the named component. -The first line of the message in a commit and tag object is -`subject`, the remaining lines are `body`. The whole message -is `contents`. +The complete message in a commit and tag object is `contents`. +Its first line is `contents:subject`, the remaining lines +are `contents:body` and the optional GPG signature +is `contents:signature`. For sorting purposes, fields with numeric values sort in numeric order (`objectsize`, `authordate`, `committerdate`, `taggerdate`). diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 89e75c6..e320ba2 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -69,6 +69,9 @@ static struct { { "subject" }, { "body" }, { "contents" }, + { "contents:subject" }, + { "contents:body" }, + { "contents:signature" }, { "upstream" }, { "symref" }, { "flag" }, @@ -458,8 +461,9 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru } } -static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body) +static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body, const char **signature) { + *signature = buf + parse_signature(buf, sz); while (*buf) { const char *eol = strchr(buf, '\n'); if (!eol) @@ -475,21 +479,21 @@ static void find_subpos(const char *buf, unsigned long sz, const char **sub, con if (!*buf) return; *sub = buf; /* first non-empty line */ - buf = strchr(buf, '\n'); - if (!buf) { - *body = ""; - return; /* no body */ - } - while (*buf == '\n') - buf++; /* skip blank between subject and body */ - *body = buf; + buf = format_subject(NULL, buf, NULL); + + /* When having a signed tag without body, format_subject() + * will start to eat the signature. */ + if (buf > *signature) + *body = *signature; + else /* - 1 to get a trailing newline to strip */ + *body = buf - 1; } /* See grab_values */ static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) { int i; - const char *subpos = NULL, *bodypos = NULL; + const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL; for (i = 0; i < used_atom_cnt; i++) { const char *name = used_atom[i]; @@ -500,19 +504,29 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj name++; if (strcmp(name, "subject") && strcmp(name, "body") && - strcmp(name, "contents")) + strcmp(name, "contents") && + strcmp(name, "contents:subject") && + strcmp(name, "contents:body") && + strcmp(name, "contents:signature")) continue; if (!subpos) - find_subpos(buf, sz, &subpos, &bodypos); + find_subpos(buf, sz, &subpos, &bodypos, &sigpos); if (!subpos) return; - if (!strcmp(name, "subject")) - v->s = copy_line(subpos); + if (!strcmp(name, "subject") || !strcmp(name, "contents:subject")) + v->s = xstrndup(subpos, bodypos - subpos - 1); else if (!strcmp(name, "body")) v->s = xstrdup(bodypos); else if (!strcmp(name, "contents")) v->s = xstrdup(subpos); + else if (!strcmp(name, "contents:body")) { + if (sigpos - bodypos > 0) + v->s = xstrndup(bodypos + 1, sigpos - bodypos - 1); + else + v->s = xstrdup(""); + } else if (!strcmp(name, "contents:signature")) + v->s = xstrdup(sigpos); } } -- 1.7.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html