git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v9 4/4] var: add broken-out identity variables

From
APAndrew Pleeter <andrewpleeter@gmail.com>
Date
Sep 26, 2026, 16:20 UTC
Message-ID
<20260926162048.30853-5-andrewpleeter@gmail.com>
In-Reply-To
<xmqq33va1lcg.fsf@gitster.g>

A script that wants only the author's name has to ask for GIT_AUTHOR_IDENT and take the result apart itself, which means reimplementing the rules split_ident_line() already knows, and getting them subtly wrong for names that contain an e-mail address or other awkward characters.

Add GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE, together with their GIT_COMMITTER_* counterparts, which give the individual pieces of the corresponding *_IDENT variable. They are derived from the same ident string, so they are strict in the same way: asking for one of them fails if the identity cannot be determined.

Signed-off-by: Andrew Pleeter <andrewpleeter@gmail.com>
---
 Documentation/git-var.adoc | 36 +++++++++++++--
 builtin/var.c              | 90 ++++++++++++++++++++++++++++++++++++++
 t/t0007-git-var.sh         | 56 ++++++++++++++++++++++++
 3 files changed, 178 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-var.adoc b/Documentation/git-var.adoc
index d0772d9743..6982228f97 100644
--- a/Documentation/git-var.adoc
+++ b/Documentation/git-var.adoc
@@ -43,17 +43,45 @@ OPTIONS
 
 EXAMPLES
 --------
-	$ git var GIT_AUTHOR_IDENT
-	Eric W. Biederman <ebiederm@lnxi.com> 1121223278 -0600
+* Get the author identity:
++
+------------
+$ git var GIT_AUTHOR_IDENT
+Eric W. Biederman <ebiederm@lnxi.com> 1121223278 -0600
+------------
+
+* Get the author name and email:
++
+------------
+$ git var GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+GIT_AUTHOR_NAME=Eric W. Biederman
+GIT_AUTHOR_EMAIL=ebiederm@lnxi.com
+------------
 
 
 VARIABLES
 ---------
 `GIT_AUTHOR_IDENT`::
-    The author of a piece of code.
+`GIT_AUTHOR_NAME`::
+`GIT_AUTHOR_EMAIL`::
+`GIT_AUTHOR_DATE`::
+    The authorship information that would be recorded in the
+    resulting commit object if you ran `git commit` right now.
+    `GIT_AUTHOR_IDENT` consists of the author's name, e-mail
+    address, and timestamp+timezone. These three pieces of
+    information are available separately as `GIT_AUTHOR_NAME`,
+    `GIT_AUTHOR_EMAIL`, and `GIT_AUTHOR_DATE`.
 
 `GIT_COMMITTER_IDENT`::
-    The person who put a piece of code into Git.
+`GIT_COMMITTER_NAME`::
+`GIT_COMMITTER_EMAIL`::
+`GIT_COMMITTER_DATE`::
+    The committer information that would be recorded in the
+    resulting commit object if you ran `git commit` right now.
+    `GIT_COMMITTER_IDENT` consists of the committer's name, e-mail
+    address, and timestamp+timezone. These three pieces of
+    information are available separately as `GIT_COMMITTER_NAME`,
+    `GIT_COMMITTER_EMAIL`, and `GIT_COMMITTER_DATE`.
 
 `GIT_EDITOR`::
     Text editor for use by Git commands.  The value is meant to be
diff --git a/builtin/var.c b/builtin/var.c
index 5fbebc62e2..dd4325e5b5 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -27,16 +27,82 @@ static const char * const var_usage[] = {
 	NULL
 };
 
+enum ident_part {
+	IDENT_NAME,
+	IDENT_MAIL,
+	IDENT_DATE,
+};
+
+static char *ident_part(const char *ident, enum ident_part part)
+{
+	struct ident_split split;
+
+	if (!ident)
+		return NULL;
+	if (split_ident_line(&split, ident, strlen(ident)))
+		return NULL;
+
+	switch (part) {
+	case IDENT_NAME:
+		if (!split.name_begin || !split.name_end)
+			BUG("split_ident_line() gave NULL names???");
+		return xmemdupz(split.name_begin,
+				split.name_end - split.name_begin);
+	case IDENT_MAIL:
+		if (!split.mail_begin || !split.mail_end)
+			BUG("split_ident_line() gave NULL mail???");
+		return xmemdupz(split.mail_begin,
+				split.mail_end - split.mail_begin);
+	case IDENT_DATE:
+		if (!split.date_begin || !split.tz_end)
+			BUG("split_ident_line() gave NULL date/tz???");
+		return xmemdupz(split.date_begin,
+				split.tz_end - split.date_begin);
+	default:
+		BUG("unknown ident_part %d", part);
+	}
+}
+
 static char *committer(int ident_flag)
 {
 	return xstrdup_or_null(git_committer_info(ident_flag));
 }
 
+static char *committer_name(int ident_flag)
+{
+	return ident_part(git_committer_info(ident_flag), IDENT_NAME);
+}
+
+static char *committer_email(int ident_flag)
+{
+	return ident_part(git_committer_info(ident_flag), IDENT_MAIL);
+}
+
+static char *committer_date(int ident_flag)
+{
+	return ident_part(git_committer_info(ident_flag), IDENT_DATE);
+}
+
 static char *author(int ident_flag)
 {
 	return xstrdup_or_null(git_author_info(ident_flag));
 }
 
+static char *author_name(int ident_flag)
+{
+	return ident_part(git_author_info(ident_flag), IDENT_NAME);
+}
+
+static char *author_email(int ident_flag)
+{
+	return ident_part(git_author_info(ident_flag), IDENT_MAIL);
+}
+
+static char *author_date(int ident_flag)
+{
+	return ident_part(git_author_info(ident_flag), IDENT_DATE);
+}
+
 static char *editor(int ident_flag UNUSED)
 {
 	return xstrdup_or_null(git_editor());
@@ -123,10 +189,34 @@ static struct git_var git_vars[] = {
 		.name = "GIT_COMMITTER_IDENT",
 		.read = committer,
 	},
+	{
+		.name = "GIT_COMMITTER_NAME",
+		.read = committer_name,
+	},
+	{
+		.name = "GIT_COMMITTER_EMAIL",
+		.read = committer_email,
+	},
+	{
+		.name = "GIT_COMMITTER_DATE",
+		.read = committer_date,
+	},
 	{
 		.name = "GIT_AUTHOR_IDENT",
 		.read = author,
 	},
+	{
+		.name = "GIT_AUTHOR_NAME",
+		.read = author_name,
+	},
+	{
+		.name = "GIT_AUTHOR_EMAIL",
+		.read = author_email,
+	},
+	{
+		.name = "GIT_AUTHOR_DATE",
+		.read = author_date,
+	},
 	{
 		.name = "GIT_EDITOR",
 		.read = editor,
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
index 593610300a..e43becff1c 100755
--- a/t/t0007-git-var.sh
+++ b/t/t0007-git-var.sh
@@ -373,4 +373,60 @@ test_expect_success 'unknown variable is a usage error' '
 	test_grep usage err
 '
 
+test_expect_success 'get author identity components' '
+	test_tick &&
+	echo "$GIT_AUTHOR_NAME" >expect.name &&
+	echo "$GIT_AUTHOR_EMAIL" >expect.email &&
+	echo "$GIT_AUTHOR_DATE" >expect.date &&
+	git var GIT_AUTHOR_NAME >actual.name &&
+	git var GIT_AUTHOR_EMAIL >actual.email &&
+	git var GIT_AUTHOR_DATE >actual.date &&
+	test_cmp expect.name actual.name &&
+	test_cmp expect.email actual.email &&
+	test_cmp expect.date actual.date
+'
+
+test_expect_success 'get committer identity components' '
+	test_tick &&
+	echo "$GIT_COMMITTER_NAME" >expect.name &&
+	echo "$GIT_COMMITTER_EMAIL" >expect.email &&
+	echo "$GIT_COMMITTER_DATE" >expect.date &&
+	git var GIT_COMMITTER_NAME >actual.name &&
+	git var GIT_COMMITTER_EMAIL >actual.email &&
+	git var GIT_COMMITTER_DATE >actual.date &&
+	test_cmp expect.name actual.name &&
+	test_cmp expect.email actual.email &&
+	test_cmp expect.date actual.date
+'
+
+test_expect_success !FAIL_PREREQS,!AUTOIDENT 'identity components are strict' '
+	(
+		sane_unset GIT_COMMITTER_NAME &&
+		sane_unset GIT_COMMITTER_EMAIL &&
+		test_must_fail git var GIT_COMMITTER_NAME
+	)
+'
+
+test_expect_success 'get several identity components at once' '
+	test_tick &&
+	cat >expect <<-EOF &&
+	GIT_AUTHOR_NAME=$GIT_AUTHOR_NAME
+	GIT_AUTHOR_EMAIL=$GIT_AUTHOR_EMAIL
+	GIT_COMMITTER_NAME=$GIT_COMMITTER_NAME
+	GIT_COMMITTER_EMAIL=$GIT_COMMITTER_EMAIL
+	EOF
+	git var GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'git var -l lists the identity components' '
+	git var -l >actual &&
+	test_grep "^GIT_AUTHOR_NAME=" actual &&
+	test_grep "^GIT_AUTHOR_EMAIL=" actual &&
+	test_grep "^GIT_AUTHOR_DATE=" actual &&
+	test_grep "^GIT_COMMITTER_NAME=" actual &&
+	test_grep "^GIT_COMMITTER_EMAIL=" actual &&
+	test_grep "^GIT_COMMITTER_DATE=" actual
+'
+
 test_done
-- 
2.54.0 (Apple Git-157)
Previous: Phillip WoodNext: Phillip Wood
Message 34 of 35 in “builtin/whoami: add new 'whoami' command”
  1. builtin/whoami: add new 'whoami' commandAndrew Pleeter via GitGitGadget, Aug 25, 2026
  2. brian m. carlsonAug 25, 2026
  3. Junio C HamanoAug 25, 2026
  4. builtin/ident: add new 'ident' commandAndrew Pleeter via GitGitGadget, Aug 31, 2026
  5. Jeff KingSep 1, 2026
  6. Junio C HamanoSep 1, 2026
  7. var: support broken-down idents, default key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 3, 2026
  8. Junio C HamanoSep 3, 2026
  9. Ben KnobleSep 3, 2026
  10. Phillip WoodSep 4, 2026
  11. Junio C HamanoSep 4, 2026
  12. Phillip WoodSep 8, 2026
  13. var: support broken-down idents, signing key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 8, 2026
  14. Phillip WoodSep 8, 2026
  15. var: support broken-down idents, signing key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 8, 2026
  16. Junio C HamanoSep 8, 2026
  17. var: support broken-down idents, signing key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 9, 2026
  18. Phillip WoodSep 9, 2026
  19. Junio C HamanoSep 9, 2026
  20. var: support broken-down idents, signing key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 10, 2026
  21. Junio C HamanoSep 14, 2026
  22. var: support broken-down idents, signing key, multiple args, and -zAndrew Pleeter via GitGitGadget, Sep 14, 2026
  23. Junio C HamanoSep 15, 2026
  24. Andrew PleeterSep 15, 2026
  25. Phillip WoodSep 22, 2026
  26. Andrew PleeterSep 26, 2026
  27. 0/4 var: -z output, multiple variables, and broken-out identsAndrew Pleeter, Sep 26, 2026
  28. Phillip WoodOct 2, 2026
  29. Andrew PleeterOct 2, 2026
  30. 1/4 var: represent multi-valued variables with a string_listAndrew Pleeter, Sep 26, 2026
  31. 2/4 var: add "-z" output modeAndrew Pleeter, Sep 26, 2026
  32. 3/4 var: accept more than one variableAndrew Pleeter, Sep 26, 2026
  33. Phillip WoodOct 2, 2026
  34. 4/4 var: add broken-out identity variablesAndrew Pleeter, Sep 26, 2026
  35. Phillip WoodOct 2, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.