Browse Source

ref-filter: support different email formats

Currently, ref-filter only supports printing email with angle brackets.

Let's add support for two more email options.
- trim : for email without angle brackets.
- localpart : for the part before the @ sign out of trimmed email

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Heba Waly <heba.waly@gmail.com>
Signed-off-by: Hariom Verma <hariom18599@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Hariom Verma 5 years ago committed by Junio C Hamano
parent
commit
b82445dc27
  1. 5
      Documentation/git-for-each-ref.txt
  2. 54
      ref-filter.c
  3. 16
      t/t6300-for-each-ref.sh

5
Documentation/git-for-each-ref.txt

@ -230,7 +230,10 @@ These are intended for working on a mix of annotated and lightweight tags. @@ -230,7 +230,10 @@ These are intended for working on a mix of annotated and lightweight tags.

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.
and `date` to extract the named component. For email fields (`authoremail`,
`committeremail` and `taggeremail`), `:trim` can be appended to get the email
without angle brackets, and `:localpart` to get the part before the `@` symbol
out of the trimmed email.

The message in a commit or a tag object is `contents`, from which
`contents:<part>` can be used to extract various parts out of:

54
ref-filter.c

@ -140,6 +140,9 @@ static struct used_atom { @@ -140,6 +140,9 @@ static struct used_atom {
enum { O_FULL, O_LENGTH, O_SHORT } option;
unsigned int length;
} objectname;
struct email_option {
enum { EO_RAW, EO_TRIM, EO_LOCALPART } option;
} email_option;
struct refname_atom refname;
char *head;
} u;
@ -377,6 +380,20 @@ static int objectname_atom_parser(const struct ref_format *format, struct used_a @@ -377,6 +380,20 @@ static int objectname_atom_parser(const struct ref_format *format, struct used_a
return 0;
}

static int person_email_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
if (!arg)
atom->u.email_option.option = EO_RAW;
else if (!strcmp(arg, "trim"))
atom->u.email_option.option = EO_TRIM;
else if (!strcmp(arg, "localpart"))
atom->u.email_option.option = EO_LOCALPART;
else
return strbuf_addf_ret(err, -1, _("unrecognized email option: %s"), arg);
return 0;
}

static int refname_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
@ -488,15 +505,15 @@ static struct { @@ -488,15 +505,15 @@ static struct {
{ "tag", SOURCE_OBJ },
{ "author", SOURCE_OBJ },
{ "authorname", SOURCE_OBJ },
{ "authoremail", SOURCE_OBJ },
{ "authoremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
{ "authordate", SOURCE_OBJ, FIELD_TIME },
{ "committer", SOURCE_OBJ },
{ "committername", SOURCE_OBJ },
{ "committeremail", SOURCE_OBJ },
{ "committeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
{ "committerdate", SOURCE_OBJ, FIELD_TIME },
{ "tagger", SOURCE_OBJ },
{ "taggername", SOURCE_OBJ },
{ "taggeremail", SOURCE_OBJ },
{ "taggeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
{ "taggerdate", SOURCE_OBJ, FIELD_TIME },
{ "creator", SOURCE_OBJ },
{ "creatordate", SOURCE_OBJ, FIELD_TIME },
@ -1037,16 +1054,35 @@ static const char *copy_name(const char *buf) @@ -1037,16 +1054,35 @@ static const char *copy_name(const char *buf)
return xstrdup("");
}

static const char *copy_email(const char *buf)
static const char *copy_email(const char *buf, struct used_atom *atom)
{
const char *email = strchr(buf, '<');
const char *eoemail;
if (!email)
return xstrdup("");
eoemail = strchr(email, '>');
switch (atom->u.email_option.option) {
case EO_RAW:
eoemail = strchr(email, '>');
if (eoemail)
eoemail++;
break;
case EO_TRIM:
email++;
eoemail = strchr(email, '>');
break;
case EO_LOCALPART:
email++;
eoemail = strchr(email, '@');
if (!eoemail)
eoemail = strchr(email, '>');
break;
default:
BUG("unknown email option");
}

if (!eoemail)
return xstrdup("");
return xmemdupz(email, eoemail + 1 - email);
return xmemdupz(email, eoemail - email);
}

static char *copy_subject(const char *buf, unsigned long len)
@ -1116,7 +1152,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void @@ -1116,7 +1152,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
continue;
if (name[wholen] != 0 &&
strcmp(name + wholen, "name") &&
strcmp(name + wholen, "email") &&
!starts_with(name + wholen, "email") &&
!starts_with(name + wholen, "date"))
continue;
if (!wholine)
@ -1127,8 +1163,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void @@ -1127,8 +1163,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
v->s = copy_line(wholine);
else if (!strcmp(name + wholen, "name"))
v->s = copy_name(wholine);
else if (!strcmp(name + wholen, "email"))
v->s = copy_email(wholine);
else if (starts_with(name + wholen, "email"))
v->s = copy_email(wholine, &used_atom[i]);
else if (starts_with(name + wholen, "date"))
grab_date(wholine, v, name);
}

16
t/t6300-for-each-ref.sh

@ -125,15 +125,21 @@ test_atom head '*objecttype' '' @@ -125,15 +125,21 @@ test_atom head '*objecttype' ''
test_atom head author 'A U Thor <author@example.com> 1151968724 +0200'
test_atom head authorname 'A U Thor'
test_atom head authoremail '<author@example.com>'
test_atom head authoremail:trim 'author@example.com'
test_atom head authoremail:localpart 'author'
test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200'
test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200'
test_atom head committername 'C O Mitter'
test_atom head committeremail '<committer@example.com>'
test_atom head committeremail:trim 'committer@example.com'
test_atom head committeremail:localpart 'committer'
test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200'
test_atom head tag ''
test_atom head tagger ''
test_atom head taggername ''
test_atom head taggeremail ''
test_atom head taggeremail:trim ''
test_atom head taggeremail:localpart ''
test_atom head taggerdate ''
test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200'
test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200'
@ -170,15 +176,21 @@ test_atom tag '*objecttype' 'commit' @@ -170,15 +176,21 @@ test_atom tag '*objecttype' 'commit'
test_atom tag author ''
test_atom tag authorname ''
test_atom tag authoremail ''
test_atom tag authoremail:trim ''
test_atom tag authoremail:localpart ''
test_atom tag authordate ''
test_atom tag committer ''
test_atom tag committername ''
test_atom tag committeremail ''
test_atom tag committeremail:trim ''
test_atom tag committeremail:localpart ''
test_atom tag committerdate ''
test_atom tag tag 'testtag'
test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200'
test_atom tag taggername 'C O Mitter'
test_atom tag taggeremail '<committer@example.com>'
test_atom tag taggeremail:trim 'committer@example.com'
test_atom tag taggeremail:localpart 'committer'
test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200'
test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200'
test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200'
@ -564,10 +576,14 @@ test_atom refs/tags/taggerless tag 'taggerless' @@ -564,10 +576,14 @@ test_atom refs/tags/taggerless tag 'taggerless'
test_atom refs/tags/taggerless tagger ''
test_atom refs/tags/taggerless taggername ''
test_atom refs/tags/taggerless taggeremail ''
test_atom refs/tags/taggerless taggeremail:trim ''
test_atom refs/tags/taggerless taggeremail:localpart ''
test_atom refs/tags/taggerless taggerdate ''
test_atom refs/tags/taggerless committer ''
test_atom refs/tags/taggerless committername ''
test_atom refs/tags/taggerless committeremail ''
test_atom refs/tags/taggerless committeremail:trim ''
test_atom refs/tags/taggerless committeremail:localpart ''
test_atom refs/tags/taggerless committerdate ''
test_atom refs/tags/taggerless subject 'Broken tag'


Loading…
Cancel
Save