[PATCH/RFC 9/9] add long forms for author and committer identity

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



this adds the long forms %(authorname), %(committername),
%(authoremail), and %(committeremail) to complement the existing
placeholders %an, %ae, %cn, and %ce; and, :mailmap forms of each, eg:
    %(authoremail:mailmap)

The main purpose of this change is to match the format of the
placeholders supported in git for-each-ref, though the optional :mailmap
parameter seemed like a sensible extension.

At this point we have enough "long form" placeholders to justify giving
them their own section in the documentation, so we do.

Signed-off-by: Will Palmer <wmpalmer@xxxxxxxxx>
---
 Documentation/pretty-formats.txt |   57 ++++++++++++++++++++++++++++----
 commit.h                         |    6 +--
 pretty.c                         |   68 ++++++++++++++++++++++++++++----------
 test-pretty.c                    |   14 +++++--
 4 files changed, 112 insertions(+), 33 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index dfb81a7..e9d6634 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -97,7 +97,13 @@ The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<
 
 --------
 +
-The placeholders are:
+The placeholders are divided into two categories, "short forms",
+for quickly typing the more-common placeholders, and "long forms",
+which may be more readable, and may support various additional
+options.
++
+--
+Short forms:
 
 - '%H': commit hash
 - '%h': abbreviated commit hash
@@ -114,8 +120,6 @@ The placeholders are:
 - '%ar': author date, relative
 - '%at': author date, UNIX timestamp
 - '%ai': author date, ISO 8601 format
-- '%(authordate[:<format>])': author date. Without a <format>, the --date= option is respected.
-  Otherwise, a format of the type which can be specified via the --date= option is taken.
 - '%cn': committer name
 - '%cN': committer name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
 - '%ce': committer email
@@ -125,8 +129,6 @@ The placeholders are:
 - '%cr': committer date, relative
 - '%ct': committer date, UNIX timestamp
 - '%ci': committer date, ISO 8601 format
-- '%(committerdate[:<format>])': committer date. Without a <format>, the --date= option is respected.
-  Otherwise, a format of the type which can be specified via the --date= option is taken.
 - '%d': ref names, like the --decorate option of linkgit:git-log[1]
 - '%e': encoding
 - '%s': subject
@@ -142,20 +144,61 @@ The placeholders are:
 - '%Cblue': switch color to blue
 - '%Creset': reset color
 - '%C(...)': color specification, as described in color.branch.* config option
-- '%(color:...)': alternative form of %C(...)
 - '%m': left, right or boundary mark
 - '%n': newline
 - '%%': a raw '%'
 - '%x00': print a byte from a hex code
 - '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
   linkgit:git-shortlog[1].
-- '%(wrap:[<w>[,<i1>[,<i2>]]])': alternative form of %w(...)
+
+Long forms:
+
+- '%(authorname[:mailmap])':
++
+author name, optionally respecting .mailmap (see linkgit:git-shortlog[1]
+or linkgit:git-blame[1]).
+
+- '%(authoremail[:mailmap])':
++
+author email, optionally respecting .mailmap (see linkgit:git-shortlog[1]
+or linkgit:git-blame[1]).
+
+- '%(authordate[:<format>])':
++
+author date. Without a <format>, the --date= option is respected.
+Otherwise, a format of the type which can be specified via the --date=
+option is taken.
+
+- '%(committername[:mailmap])':
++
+committer name, optionally respecting .mailmap (see
+linkgit:git-shortlog[1] or linkgit:git-blame[1]).
+
+- '%(committeremail[:mailmap])':
++
+committer email, optionally respecting .mailmap (see
+linkgit:git-shortlog[1] or linkgit:git-blame[1]).
+
+- '%(committerdate[:<format>])':
++
+committer date. Without a <format>, the --date= option is respected.
+Otherwise, a format of the type which can be specified via the --date=
+option is taken.
+
+- '%(color:[<spec>])':
++
+color specification, as described in color.branch.* config option.
+
+- '%(wrap:[<w>[,<i1>[,<i2>]]])':
++
+switch line wrapping, like the -w option of linkgit:git-shortlog[1].
 
 NOTE: Some placeholders may depend on other options given to the
 revision traversal engine. For example, the `%g*` reflog options will
 insert an empty string unless we are traversing reflog entries (e.g., by
 `git log -g`). The `%d` placeholder will use the "short" decoration
 format if `--decorate` was not already provided on the command line.
+--
 
 If you add a `{plus}` (plus sign) after '%' of a placeholder, a line-feed
 is inserted immediately before the expansion if and only if the
diff --git a/commit.h b/commit.h
index fff1225..a175444 100644
--- a/commit.h
+++ b/commit.h
@@ -95,14 +95,10 @@ enum format_part_type {
 	FORMAT_PART_TREE_HASH_ABBREV,
 
 	FORMAT_PART_AUTHOR_NAME,
-	FORMAT_PART_AUTHOR_NAME_MAILMAP,
 	FORMAT_PART_AUTHOR_EMAIL,
-	FORMAT_PART_AUTHOR_EMAIL_MAILMAP,
 	FORMAT_PART_AUTHOR_DATE,
 	FORMAT_PART_COMMITTER_NAME,
-	FORMAT_PART_COMMITTER_NAME_MAILMAP,
 	FORMAT_PART_COMMITTER_EMAIL,
-	FORMAT_PART_COMMITTER_EMAIL_MAILMAP,
 	FORMAT_PART_COMMITTER_DATE,
 
 	FORMAT_PART_DECORATE,
@@ -130,6 +126,7 @@ enum format_part_magic {
 
 enum format_arg_type {
 	FORMAT_ARG_UINT,
+	FORMAT_ARG_BOOLEAN,
 	FORMAT_ARG_DATE_MODE
 };
 
@@ -137,6 +134,7 @@ struct format_arg {
 	enum format_arg_type type;
 	union {
 		unsigned long uint;
+		int boolean : 1;
 		enum date_mode dmode;
 	};
 };
diff --git a/pretty.c b/pretty.c
index 006bbe3..ef6c3c1 100644
--- a/pretty.c
+++ b/pretty.c
@@ -90,6 +90,16 @@ static void part_add_arg_date_mode(struct format_part *part,
 	return;
 }
 
+static void part_add_arg_boolean(struct format_part *part, int value)
+{
+	part->args = xrealloc(part->args,
+			      sizeof(struct format_arg) * (part->argc+1));
+	part->args[part->argc].type = FORMAT_ARG_BOOLEAN;
+	part->args[part->argc].boolean = value ? 1 : 0;
+	part->argc++;
+	return;
+}
+
 /*
 * Parse a single argument of an extended format, up to the next delimiter
 * ie: up to ',' or ')'
@@ -165,6 +175,31 @@ static struct format_part *parse_extended(const char *unparsed)
 				goto fail;
 			goto success;
 		}
+		if (!prefixcmp(c, "name") || !prefixcmp(c, "email")) {
+			if (*c == 'n') { /* name */
+				part->type = (*e == 'a') ? FORMAT_PART_AUTHOR_NAME :
+							   FORMAT_PART_COMMITTER_NAME;
+				c += 4;
+			} else { /* email */
+				part->type = (*e == 'a') ? FORMAT_PART_AUTHOR_EMAIL :
+							   FORMAT_PART_COMMITTER_EMAIL;
+				c += 5;
+			}
+
+			strspn(c, WHITESPACE);
+			if (*c == ')')
+				goto success;
+			if (*c != ':')
+				goto fail;
+			c += 1 + strspn(c + 1, WHITESPACE);
+			if (!prefixcmp(c, "mailmap")) {
+				part_add_arg_boolean(part, 1);
+				c += 7 + strspn(c + 7, WHITESPACE);
+				if (*c == ')')
+					goto success;
+			}
+			goto fail;
+		}
 
 		c = e;
 	}
@@ -285,13 +320,15 @@ static struct format_part *parse_special(const char *unparsed)
 			part->type = FORMAT_PART_AUTHOR_NAME;
 			return part;
 		case 'N':
-			part->type = FORMAT_PART_AUTHOR_NAME_MAILMAP;
+			part->type = FORMAT_PART_AUTHOR_NAME;
+			part_add_arg_boolean(part, 1);
 			return part;
 		case 'e':
 			part->type = FORMAT_PART_AUTHOR_EMAIL;
 			return part;
 		case 'E':
-			part->type = FORMAT_PART_AUTHOR_EMAIL_MAILMAP;
+			part->type = FORMAT_PART_AUTHOR_EMAIL;
+			part_add_arg_boolean(part, 1);
 			return part;
 		case 'd':
 			part->type = FORMAT_PART_AUTHOR_DATE;
@@ -321,13 +358,15 @@ static struct format_part *parse_special(const char *unparsed)
 			part->type = FORMAT_PART_COMMITTER_NAME;
 			return part;
 		case 'N':
-			part->type = FORMAT_PART_COMMITTER_NAME_MAILMAP;
+			part->type = FORMAT_PART_COMMITTER_NAME;
+			part_add_arg_boolean(part, 1);
 			return part;
 		case 'e':
 			part->type = FORMAT_PART_COMMITTER_EMAIL;
 			return part;
 		case 'E':
-			part->type = FORMAT_PART_COMMITTER_EMAIL_MAILMAP;
+			part->type = FORMAT_PART_COMMITTER_EMAIL;
+			part_add_arg_boolean(part, 1);
 			return part;
 		case 'd':
 			part->type = FORMAT_PART_COMMITTER_DATE;
@@ -976,10 +1015,11 @@ static void format_person_part(struct strbuf *sb, struct format_part *part,
 		return;
 	end = mail_end-msg;
 
-	if (part->type == FORMAT_PART_AUTHOR_NAME_MAILMAP ||
-	    part->type == FORMAT_PART_AUTHOR_EMAIL_MAILMAP ||
-	    part->type == FORMAT_PART_COMMITTER_NAME_MAILMAP ||
-	    part->type == FORMAT_PART_COMMITTER_EMAIL_MAILMAP) {
+	if ((part->type == FORMAT_PART_AUTHOR_NAME ||
+	     part->type == FORMAT_PART_AUTHOR_EMAIL ||
+	     part->type == FORMAT_PART_COMMITTER_NAME ||
+	     part->type == FORMAT_PART_COMMITTER_EMAIL) &&
+	    part->argc && part->args[0].boolean) { /* mailmap */
 		/* copy up to, and including, the end delimiter */
 		strlcpy(person_name, name_start, name_len+1);
 		strlcpy(person_mail, mail_start, mail_len+1);
@@ -990,16 +1030,12 @@ static void format_person_part(struct strbuf *sb, struct format_part *part,
 		mail_len = strlen(person_mail);
 	}
 	if (part->type == FORMAT_PART_AUTHOR_NAME ||
-	    part->type == FORMAT_PART_AUTHOR_NAME_MAILMAP ||
-	    part->type == FORMAT_PART_COMMITTER_NAME ||
-	    part->type == FORMAT_PART_COMMITTER_NAME_MAILMAP) {
+	    part->type == FORMAT_PART_COMMITTER_NAME) {
 		strbuf_add(sb, name_start, name_len);
 		return;
 	}
 	if (part->type == FORMAT_PART_AUTHOR_EMAIL ||
-	    part->type == FORMAT_PART_AUTHOR_EMAIL_MAILMAP ||
-	    part->type == FORMAT_PART_COMMITTER_EMAIL ||
-	    part->type == FORMAT_PART_COMMITTER_EMAIL_MAILMAP) {
+	    part->type == FORMAT_PART_COMMITTER_EMAIL) {
 		strbuf_add(sb, mail_start, mail_len);
 		return;
 	}
@@ -1338,17 +1374,13 @@ void format_commit_message_part(struct format_part *part,
 
 	switch (part->type) {
 	case FORMAT_PART_AUTHOR_NAME:
-	case FORMAT_PART_AUTHOR_NAME_MAILMAP:
 	case FORMAT_PART_AUTHOR_EMAIL:
-	case FORMAT_PART_AUTHOR_EMAIL_MAILMAP:
 	case FORMAT_PART_AUTHOR_DATE:
 		format_person_part(sb, part, commit->buffer + c->author.off,
 				   c->author.len, c->pretty_ctx->date_mode);
 		return;
 	case FORMAT_PART_COMMITTER_NAME:
-	case FORMAT_PART_COMMITTER_NAME_MAILMAP:
 	case FORMAT_PART_COMMITTER_EMAIL:
-	case FORMAT_PART_COMMITTER_EMAIL_MAILMAP:
 	case FORMAT_PART_COMMITTER_DATE:
 		format_person_part(sb, part, commit->buffer + c->committer.off,
 				   c->committer.len, c->pretty_ctx->date_mode);
diff --git a/test-pretty.c b/test-pretty.c
index 6a92c65..f9d44fa 100644
--- a/test-pretty.c
+++ b/test-pretty.c
@@ -19,11 +19,15 @@ static const char *all = "a"
 "%m%w()%w(1)%w(1,2)%w(1,2,3)"
 "%(wrap)%(wrap:1)%(wrap:1,2)%(wrap:1,2,3)"
 "%(color)%(color:red)%(color:red bold)%(color:red green bold)"
+"%(authorname)%(authorname:mailmap)"
+"%(authoremail)%(authoremail:mailmap)"
 "%(authordate)%(authordate:default)%(authordate:relative)"
 "%(authordate:short)%(authordate:local)"
 "%(authordate:iso8601)%(authordate:iso)"
 "%(authordate:rfc2822)%(authordate:rfc)"
 "%(authordate:unix)%(authordate:raw)"
+"%(committername)%(committername:mailmap)"
+"%(committeremail)%(committeremail:mailmap)"
 "%(committerdate)%(committerdate:default)%(committerdate:relative)"
 "%(committerdate:short)%(committerdate:local)"
 "%(committerdate:iso8601)%(committerdate:iso)"
@@ -46,14 +50,10 @@ static struct strbuf *parts_debug(struct format_parts *parts,
 		{FORMAT_PART_TREE_HASH, "TREE_HASH"},
 		{FORMAT_PART_TREE_HASH_ABBREV, "TREE_HASH_ABBREV"},
 		{FORMAT_PART_AUTHOR_NAME, "AUTHOR_NAME"},
-		{FORMAT_PART_AUTHOR_NAME_MAILMAP, "AUTHOR_NAME_MAILMAP"},
 		{FORMAT_PART_AUTHOR_EMAIL, "AUTHOR_EMAIL"},
-		{FORMAT_PART_AUTHOR_EMAIL_MAILMAP, "AUTHOR_EMAIL_MAILMAP"},
 		{FORMAT_PART_AUTHOR_DATE, "AUTHOR_DATE"},
 		{FORMAT_PART_COMMITTER_NAME, "COMMITTER_NAME"},
-		{FORMAT_PART_COMMITTER_NAME_MAILMAP, "COMMITTER_NAME_MAILMAP"},
 		{FORMAT_PART_COMMITTER_EMAIL, "COMMITTER_EMAIL"},
-		{FORMAT_PART_COMMITTER_EMAIL_MAILMAP, "COMMITTER_EMAIL_MAILMAP"},
 		{FORMAT_PART_COMMITTER_DATE, "COMMITTER_DATE"},
 
 		{FORMAT_PART_DECORATE, "DECORATE"},
@@ -155,6 +155,12 @@ static struct strbuf *parts_debug(struct format_parts *parts,
 					strbuf_addstr(buf, "UINT:");
 					strbuf_addf(buf, "%lu", part->args[j].uint);
 					break;
+				case FORMAT_ARG_BOOLEAN:
+					strbuf_addstr(buf, "BOOLEAN:");
+					strbuf_addstr(buf,
+						      part->args[j].boolean ?
+						       "TRUE" : "FALSE");
+					break;
 				case FORMAT_ARG_DATE_MODE:
 					strbuf_addstr(buf, "DATE_MODE:");
 					switch(part->args[j].dmode){
-- 
1.7.4.2

--
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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]