Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-09-09 23:53:07 +0300
committerJunio C Hamano <gitster@pobox.com>2020-09-09 23:53:07 +0300
commitc25fba986bfc737d775430d290b93136d390e067 (patch)
treee14ed769e7998d7ccf26066ddb02e0b48904c82d /ref-filter.c
parent9f7833fd55c0039ef304beea7c1263d428410b95 (diff)
parent905f0a4e64bef35482a999dd01c64945b260c010 (diff)
Merge branch 'hv/ref-filter-misc'
The "--format=" option to the "for-each-ref" command and friends learned a few more tricks, e.g. the ":short" suffix that applies to "objectname" now also can be used for "parent", "tree", etc. * hv/ref-filter-misc: ref-filter: add `sanitize` option for 'subject' atom pretty: refactor `format_sanitized_subject()` ref-filter: add `short` modifier to 'parent' atom ref-filter: add `short` modifier to 'tree' atom ref-filter: rename `objectname` related functions and fields ref-filter: modify error messages in `grab_objectname()` ref-filter: refactor `grab_objectname()` ref-filter: support different email formats
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c158
1 files changed, 103 insertions, 55 deletions
diff --git a/ref-filter.c b/ref-filter.c
index 8ba0e31915..110bcd741a 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -127,8 +127,8 @@ static struct used_atom {
unsigned int nobracket : 1, push : 1, push_remote : 1;
} remote_ref;
struct {
- enum { C_BARE, C_BODY, C_BODY_DEP, C_LENGTH,
- C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
+ enum { C_BARE, C_BODY, C_BODY_DEP, C_LENGTH, C_LINES,
+ C_SIG, C_SUB, C_SUB_SANITIZE, C_TRAILERS } option;
struct process_trailer_options trailer_opts;
unsigned int nlines;
} contents;
@@ -139,7 +139,10 @@ static struct used_atom {
struct {
enum { O_FULL, O_LENGTH, O_SHORT } option;
unsigned int length;
- } objectname;
+ } oid;
+ struct email_option {
+ enum { EO_RAW, EO_TRIM, EO_LOCALPART } option;
+ } email_option;
struct refname_atom refname;
char *head;
} u;
@@ -298,9 +301,12 @@ static int body_atom_parser(const struct ref_format *format, struct used_atom *a
static int subject_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
- if (arg)
- return strbuf_addf_ret(err, -1, _("%%(subject) does not take arguments"));
- atom->u.contents.option = C_SUB;
+ if (!arg)
+ atom->u.contents.option = C_SUB;
+ else if (!strcmp(arg, "sanitize"))
+ atom->u.contents.option = C_SUB_SANITIZE;
+ else
+ return strbuf_addf_ret(err, -1, _("unrecognized %%(subject) argument: %s"), arg);
return 0;
}
@@ -360,22 +366,36 @@ static int contents_atom_parser(const struct ref_format *format, struct used_ato
return 0;
}
-static int objectname_atom_parser(const struct ref_format *format, struct used_atom *atom,
- const char *arg, struct strbuf *err)
+static int oid_atom_parser(const struct ref_format *format, struct used_atom *atom,
+ const char *arg, struct strbuf *err)
{
if (!arg)
- atom->u.objectname.option = O_FULL;
+ atom->u.oid.option = O_FULL;
else if (!strcmp(arg, "short"))
- atom->u.objectname.option = O_SHORT;
+ atom->u.oid.option = O_SHORT;
else if (skip_prefix(arg, "short=", &arg)) {
- atom->u.objectname.option = O_LENGTH;
- if (strtoul_ui(arg, 10, &atom->u.objectname.length) ||
- atom->u.objectname.length == 0)
- return strbuf_addf_ret(err, -1, _("positive value expected objectname:short=%s"), arg);
- if (atom->u.objectname.length < MINIMUM_ABBREV)
- atom->u.objectname.length = MINIMUM_ABBREV;
+ atom->u.oid.option = O_LENGTH;
+ if (strtoul_ui(arg, 10, &atom->u.oid.length) ||
+ atom->u.oid.length == 0)
+ return strbuf_addf_ret(err, -1, _("positive value expected '%s' in %%(%s)"), arg, atom->name);
+ if (atom->u.oid.length < MINIMUM_ABBREV)
+ atom->u.oid.length = MINIMUM_ABBREV;
} else
- return strbuf_addf_ret(err, -1, _("unrecognized %%(objectname) argument: %s"), arg);
+ return strbuf_addf_ret(err, -1, _("unrecognized argument '%s' in %%(%s)"), arg, atom->name);
+ 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;
}
@@ -480,25 +500,25 @@ static struct {
{ "refname", SOURCE_NONE, FIELD_STR, refname_atom_parser },
{ "objecttype", SOURCE_OTHER, FIELD_STR, objecttype_atom_parser },
{ "objectsize", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },
- { "objectname", SOURCE_OTHER, FIELD_STR, objectname_atom_parser },
+ { "objectname", SOURCE_OTHER, FIELD_STR, oid_atom_parser },
{ "deltabase", SOURCE_OTHER, FIELD_STR, deltabase_atom_parser },
- { "tree", SOURCE_OBJ },
- { "parent", SOURCE_OBJ },
+ { "tree", SOURCE_OBJ, FIELD_STR, oid_atom_parser },
+ { "parent", SOURCE_OBJ, FIELD_STR, oid_atom_parser },
{ "numparent", SOURCE_OBJ, FIELD_ULONG },
{ "object", SOURCE_OBJ },
{ "type", SOURCE_OBJ },
{ "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 },
@@ -903,21 +923,27 @@ int verify_ref_format(struct ref_format *format)
return 0;
}
-static int grab_objectname(const char *name, const struct object_id *oid,
- struct atom_value *v, struct used_atom *atom)
+static const char *do_grab_oid(const char *field, const struct object_id *oid,
+ struct used_atom *atom)
{
- if (starts_with(name, "objectname")) {
- if (atom->u.objectname.option == O_SHORT) {
- v->s = xstrdup(find_unique_abbrev(oid, DEFAULT_ABBREV));
- return 1;
- } else if (atom->u.objectname.option == O_FULL) {
- v->s = xstrdup(oid_to_hex(oid));
- return 1;
- } else if (atom->u.objectname.option == O_LENGTH) {
- v->s = xstrdup(find_unique_abbrev(oid, atom->u.objectname.length));
- return 1;
- } else
- BUG("unknown %%(objectname) option");
+ switch (atom->u.oid.option) {
+ case O_FULL:
+ return oid_to_hex(oid);
+ case O_LENGTH:
+ return find_unique_abbrev(oid, atom->u.oid.length);
+ case O_SHORT:
+ return find_unique_abbrev(oid, DEFAULT_ABBREV);
+ default:
+ BUG("unknown %%(%s) option", field);
+ }
+}
+
+static int grab_oid(const char *name, const char *field, const struct object_id *oid,
+ struct atom_value *v, struct used_atom *atom)
+{
+ if (starts_with(name, field)) {
+ v->s = xstrdup(do_grab_oid(field, oid, atom));
+ return 1;
}
return 0;
}
@@ -945,7 +971,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
} else if (!strcmp(name, "deltabase"))
v->s = xstrdup(oid_to_hex(&oi->delta_base_oid));
else if (deref)
- grab_objectname(name, &oi->oid, v, &used_atom[i]);
+ grab_oid(name, "objectname", &oi->oid, v, &used_atom[i]);
}
}
@@ -984,21 +1010,20 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
continue;
if (deref)
name++;
- if (!strcmp(name, "tree")) {
- v->s = xstrdup(oid_to_hex(get_commit_tree_oid(commit)));
- }
- else if (!strcmp(name, "numparent")) {
+ if (grab_oid(name, "tree", get_commit_tree_oid(commit), v, &used_atom[i]))
+ continue;
+ if (!strcmp(name, "numparent")) {
v->value = commit_list_count(commit->parents);
v->s = xstrfmt("%lu", (unsigned long)v->value);
}
- else if (!strcmp(name, "parent")) {
+ else if (starts_with(name, "parent")) {
struct commit_list *parents;
struct strbuf s = STRBUF_INIT;
for (parents = commit->parents; parents; parents = parents->next) {
- struct commit *parent = parents->item;
+ struct object_id *oid = &parents->item->object.oid;
if (parents != commit->parents)
strbuf_addch(&s, ' ');
- strbuf_addstr(&s, oid_to_hex(&parent->object.oid));
+ strbuf_addstr(&s, do_grab_oid("parent", oid, &used_atom[i]));
}
v->s = strbuf_detach(&s, NULL);
}
@@ -1039,16 +1064,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)
@@ -1118,7 +1162,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)
@@ -1129,8 +1173,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);
}
@@ -1243,8 +1287,8 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
continue;
if (deref)
name++;
- if (strcmp(name, "subject") &&
- strcmp(name, "body") &&
+ if (strcmp(name, "body") &&
+ !starts_with(name, "subject") &&
!starts_with(name, "trailers") &&
!starts_with(name, "contents"))
continue;
@@ -1256,7 +1300,11 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
if (atom->u.contents.option == C_SUB)
v->s = copy_subject(subpos, sublen);
- else if (atom->u.contents.option == C_BODY_DEP)
+ else if (atom->u.contents.option == C_SUB_SANITIZE) {
+ struct strbuf sb = STRBUF_INIT;
+ format_sanitized_subject(&sb, subpos, sublen);
+ v->s = strbuf_detach(&sb, NULL);
+ } else if (atom->u.contents.option == C_BODY_DEP)
v->s = xmemdupz(bodypos, bodylen);
else if (atom->u.contents.option == C_LENGTH)
v->s = xstrfmt("%"PRIuMAX, (uintmax_t)strlen(subpos));
@@ -1706,7 +1754,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
v->s = xstrdup(buf + 1);
}
continue;
- } else if (!deref && grab_objectname(name, &ref->objectname, v, atom)) {
+ } else if (!deref && grab_oid(name, "objectname", &ref->objectname, v, atom)) {
continue;
} else if (!strcmp(name, "HEAD")) {
if (atom->u.head && !strcmp(ref->refname, atom->u.head))