var: add broken-out identity variables

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Andrew Pleeter authored and Junio C Hamano committed 2026-09-26 21:31:46 -07:00
1 parent 09726e777e
commit 598588c155
3 files changed
+178 -4

No files matched your search

+32 -4
View File
@@ -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
+90
View File
@@ -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,
+56
View File
@@ -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