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>
Hariom Verma committed
Aug 21, 2020 at 21:41 UTC
b82445dc2789f2046831621e6be7b2af464af6e9
3 files changed
+65
-10
Documentation/git-for-each-ref.txt
+4
-1
@@ -230,7 +230,10 @@ These are intended for working on a mix of annotated and lightweight tags.
230
231
Fields that have name-email-date tuple as its value (`author`,
232
`committer`, and `tagger`) can be suffixed with `name`, `email`,
233
-and `date` to extract the named component.
233
+and `date` to extract the named component. For email fields (`authoremail`,
234
+`committeremail` and `taggeremail`), `:trim` can be appended to get the email
235
+without angle brackets, and `:localpart` to get the part before the `@` symbol
236
+out of the trimmed email.
237
238
The message in a commit or a tag object is `contents`, from which
239
`contents:<part>` can be used to extract various parts out of:
ref-filter.c
+45
-9
@@ -140,6 +140,9 @@ static struct used_atom {
140
enum { O_FULL, O_LENGTH, O_SHORT } option;
141
unsigned int length;
142
} objectname;
143
+ struct email_option {
144
+ enum { EO_RAW, EO_TRIM, EO_LOCALPART } option;
145
+ } email_option;
146
struct refname_atom refname;
147
char *head;
148
} u;
@@ -377,6 +380,20 @@ static int objectname_atom_parser(const struct ref_format *format, struct used_a
380
return 0;
381
}
382
383
+static int person_email_atom_parser(const struct ref_format *format, struct used_atom *atom,
384
+ const char *arg, struct strbuf *err)
385
+{
386
+ if (!arg)
387
+ atom->u.email_option.option = EO_RAW;
388
+ else if (!strcmp(arg, "trim"))
389
+ atom->u.email_option.option = EO_TRIM;
390
+ else if (!strcmp(arg, "localpart"))
391
+ atom->u.email_option.option = EO_LOCALPART;
392
+ else
393
+ return strbuf_addf_ret(err, -1, _("unrecognized email option: %s"), arg);
394
+ return 0;
395
+}
396
+
397
static int refname_atom_parser(const struct ref_format *format, struct used_atom *atom,
398
const char *arg, struct strbuf *err)
399
{
@@ -488,15 +505,15 @@ static struct {
505
{ "tag", SOURCE_OBJ },
506
{ "author", SOURCE_OBJ },
507
{ "authorname", SOURCE_OBJ },
491
- { "authoremail", SOURCE_OBJ },
508
+ { "authoremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
509
{ "authordate", SOURCE_OBJ, FIELD_TIME },
510
{ "committer", SOURCE_OBJ },
511
{ "committername", SOURCE_OBJ },
495
- { "committeremail", SOURCE_OBJ },
512
+ { "committeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
513
{ "committerdate", SOURCE_OBJ, FIELD_TIME },
514
{ "tagger", SOURCE_OBJ },
515
{ "taggername", SOURCE_OBJ },
499
- { "taggeremail", SOURCE_OBJ },
516
+ { "taggeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
517
{ "taggerdate", SOURCE_OBJ, FIELD_TIME },
518
{ "creator", SOURCE_OBJ },
519
{ "creatordate", SOURCE_OBJ, FIELD_TIME },
@@ -1037,16 +1054,35 @@ static const char *copy_name(const char *buf)
1054
return xstrdup("");
1055
}
1056
1040
-static const char *copy_email(const char *buf)
1057
+static const char *copy_email(const char *buf, struct used_atom *atom)
1058
{
1059
const char *email = strchr(buf, '<');
1060
const char *eoemail;
1061
if (!email)
1062
return xstrdup("");
1046
- eoemail = strchr(email, '>');
1063
+ switch (atom->u.email_option.option) {
1064
+ case EO_RAW:
1065
+ eoemail = strchr(email, '>');
1066
+ if (eoemail)
1067
+ eoemail++;
1068
+ break;
1069
+ case EO_TRIM:
1070
+ email++;
1071
+ eoemail = strchr(email, '>');
1072
+ break;
1073
+ case EO_LOCALPART:
1074
+ email++;
1075
+ eoemail = strchr(email, '@');
1076
+ if (!eoemail)
1077
+ eoemail = strchr(email, '>');
1078
+ break;
1079
+ default:
1080
+ BUG("unknown email option");
1081
+ }
1082
+
1083
if (!eoemail)
1084
return xstrdup("");
1049
- return xmemdupz(email, eoemail + 1 - email);
1085
+ return xmemdupz(email, eoemail - email);
1086
}
1087
1088
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
1152
continue;
1153
if (name[wholen] != 0 &&
1154
strcmp(name + wholen, "name") &&
1119
- strcmp(name + wholen, "email") &&
1155
+ !starts_with(name + wholen, "email") &&
1156
!starts_with(name + wholen, "date"))
1157
continue;
1158
if (!wholine)
@@ -1127,8 +1163,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
1163
v->s = copy_line(wholine);
1164
else if (!strcmp(name + wholen, "name"))
1165
v->s = copy_name(wholine);
1130
- else if (!strcmp(name + wholen, "email"))
1131
- v->s = copy_email(wholine);
1166
+ else if (starts_with(name + wholen, "email"))
1167
+ v->s = copy_email(wholine, &used_atom[i]);
1168
else if (starts_with(name + wholen, "date"))
1169
grab_date(wholine, v, name);
1170
}
t/t6300-for-each-ref.sh
+16
@@ -125,15 +125,21 @@ test_atom head '*objecttype' ''
125
test_atom head author 'A U Thor <author@example.com> 1151968724 +0200'
126
test_atom head authorname 'A U Thor'
127
test_atom head authoremail '<author@example.com>'
128
+test_atom head authoremail:trim 'author@example.com'
129
+test_atom head authoremail:localpart 'author'
130
test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200'
131
test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200'
132
test_atom head committername 'C O Mitter'
133
test_atom head committeremail '<committer@example.com>'
134
+test_atom head committeremail:trim 'committer@example.com'
135
+test_atom head committeremail:localpart 'committer'
136
test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200'
137
test_atom head tag ''
138
test_atom head tagger ''
139
test_atom head taggername ''
140
test_atom head taggeremail ''
141
+test_atom head taggeremail:trim ''
142
+test_atom head taggeremail:localpart ''
143
test_atom head taggerdate ''
144
test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200'
145
test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200'
@@ -170,15 +176,21 @@ test_atom tag '*objecttype' 'commit'
176
test_atom tag author ''
177
test_atom tag authorname ''
178
test_atom tag authoremail ''
179
+test_atom tag authoremail:trim ''
180
+test_atom tag authoremail:localpart ''
181
test_atom tag authordate ''
182
test_atom tag committer ''
183
test_atom tag committername ''
184
test_atom tag committeremail ''
185
+test_atom tag committeremail:trim ''
186
+test_atom tag committeremail:localpart ''
187
test_atom tag committerdate ''
188
test_atom tag tag 'testtag'
189
test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200'
190
test_atom tag taggername 'C O Mitter'
191
test_atom tag taggeremail '<committer@example.com>'
192
+test_atom tag taggeremail:trim 'committer@example.com'
193
+test_atom tag taggeremail:localpart 'committer'
194
test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200'
195
test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200'
196
test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200'
@@ -564,10 +576,14 @@ test_atom refs/tags/taggerless tag 'taggerless'
576
test_atom refs/tags/taggerless tagger ''
577
test_atom refs/tags/taggerless taggername ''
578
test_atom refs/tags/taggerless taggeremail ''
579
+test_atom refs/tags/taggerless taggeremail:trim ''
580
+test_atom refs/tags/taggerless taggeremail:localpart ''
581
test_atom refs/tags/taggerless taggerdate ''
582
test_atom refs/tags/taggerless committer ''
583
test_atom refs/tags/taggerless committername ''
584
test_atom refs/tags/taggerless committeremail ''
585
+test_atom refs/tags/taggerless committeremail:trim ''
586
+test_atom refs/tags/taggerless committeremail:localpart ''
587
test_atom refs/tags/taggerless committerdate ''
588
test_atom refs/tags/taggerless subject 'Broken tag'
589