In order to make git cat-file --batch use ref-filter logic, %(raw) atom is adding to ref-filter. Change from last version: 1. Change --<lang> and --format=%(raw) checkpoint to verify_ref_format(), which make it more scalable. 2. Change grab_sub_body_contents() use struct expand_data *data instread of using obj,buf,buf_size to pass object info which can reduce the delivery of function parameters. ZheNing Hu (2): [GSOC] ref-filter: add obj-type check in grab contents [GSOC] ref-filter: add %(raw) atom Documentation/git-for-each-ref.txt | 9 ++ ref-filter.c | 164 +++++++++++++++++------ t/t6300-for-each-ref.sh | 207 +++++++++++++++++++++++++++++ 3 files changed, 343 insertions(+), 37 deletions(-) base-commit: 1197f1a46360d3ae96bd9c15908a3a6f8e562207 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-966%2Fadlternative%2Fref-filter-raw-atom-v4-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-966/adlternative/ref-filter-raw-atom-v4-v2 Pull-Request: https://github.com/gitgitgadget/git/pull/966 Range-diff vs v1: 1: 97955705c22e ! 1: 48d256db5c34 [GSOC] ref-filter: add obj-type check in grab contents @@ ref-filter.c: static void append_lines(struct strbuf *out, const char *buf, unsi /* See grab_values */ -static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf) -+static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf, -+ struct object *obj) ++static void grab_sub_body_contents(struct atom_value *val, int deref, struct expand_data *data) { int i; const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL; + size_t sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0; ++ void *buf = data->content; + + for (i = 0; i < used_atom_cnt; i++) { + struct used_atom *atom = &used_atom[i]; @@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf) continue; if (deref) @@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int der - !starts_with(name, "trailers") && - !starts_with(name, "contents")) + -+ if ((obj->type != OBJ_TAG && -+ obj->type != OBJ_COMMIT) || ++ if ((data->type != OBJ_TAG && ++ data->type != OBJ_COMMIT) || + (strcmp(name, "body") && + !starts_with(name, "subject") && + !starts_with(name, "trailers") && @@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int der continue; if (!subpos) find_subpos(buf, -@@ ref-filter.c: static void grab_values(struct atom_value *val, int deref, struct object *obj, v +@@ ref-filter.c: static void fill_missing_values(struct atom_value *val) + * pointed at by the ref itself; otherwise it is the object the + * ref (which is a tag) refers to. + */ +-static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf) ++static void grab_values(struct atom_value *val, int deref, struct object *obj, struct expand_data *data) + { ++ void *buf = data->content; ++ switch (obj->type) { case OBJ_TAG: grab_tag_values(val, deref, obj); - grab_sub_body_contents(val, deref, buf); -+ grab_sub_body_contents(val, deref, buf, obj); ++ grab_sub_body_contents(val, deref, data); grab_person("tagger", val, deref, buf); break; case OBJ_COMMIT: grab_commit_values(val, deref, obj); - grab_sub_body_contents(val, deref, buf); -+ grab_sub_body_contents(val, deref, buf, obj); ++ grab_sub_body_contents(val, deref, data); grab_person("author", val, deref, buf); grab_person("committer", val, deref, buf); break; +@@ ref-filter.c: static int get_object(struct ref_array_item *ref, int deref, struct object **obj + return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"), + oid_to_hex(&oi->oid), ref->refname); + } +- grab_values(ref->value, deref, *obj, oi->content); ++ grab_values(ref->value, deref, *obj, oi); + } + + grab_common_values(ref->value, deref, oi); 2: 5a94705cdbc1 ! 2: 0efed9435b59 [GSOC] ref-filter: add %(raw) atom @@ ref-filter.c: static int parse_ref_filter_atom(const struct ref_format *format, arg = memchr(sp, ':', ep - sp); atom_len = (arg ? arg : ep) - sp; -+ if (format->quote_style && !strncmp(sp, "raw", 3) && !arg) -+ return strbuf_addf_ret(err, -1, _("--format=%.*s cannot be used with" -+ "--python, --shell, --tcl, --perl"), (int)(ep-atom), atom); -+ + /* Do we have the atom already used elsewhere? */ + for (i = 0; i < used_atom_cnt; i++) { + int len = strlen(used_atom[i].name); @@ ref-filter.c: static int end_atom_handler(struct atom_value *atomv, struct ref_f strbuf_swap(¤t->output, &s); } strbuf_release(&s); -@@ ref-filter.c: static void append_lines(struct strbuf *out, const char *buf, unsigned long size +@@ ref-filter.c: int verify_ref_format(struct ref_format *format) + at = parse_ref_filter_atom(format, sp + 2, ep, &err); + if (at < 0) + die("%s", err.buf); ++ if (format->quote_style && used_atom[at].atom_type == ATOM_RAW && ++ used_atom[at].u.raw_data.option == RAW_BARE) ++ die(_("--format=%.*s cannot be used with" ++ "--python, --shell, --tcl, --perl"), (int)(ep - sp - 2), sp + 2); + cp = ep + 1; - /* See grab_values */ - static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf, -- struct object *obj) -+ unsigned long buf_size, struct object *obj) - { - int i; + if (skip_prefix(used_atom[at].name, "color:", &color)) +@@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int deref, struct exp const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL; -@@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf, + size_t sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0; + void *buf = data->content; ++ unsigned long buf_size = data->size; + + for (i = 0; i < used_atom_cnt; i++) { struct used_atom *atom = &used_atom[i]; const char *name = atom->name; struct atom_value *v = &val[i]; @@ ref-filter.c: static void grab_sub_body_contents(struct atom_value *val, int der + continue; + } + - if ((obj->type != OBJ_TAG && - obj->type != OBJ_COMMIT) || + if ((data->type != OBJ_TAG && + data->type != OBJ_COMMIT) || (strcmp(name, "body") && -@@ ref-filter.c: static void fill_missing_values(struct atom_value *val) - * pointed at by the ref itself; otherwise it is the object the - * ref (which is a tag) refers to. - */ --static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf) -+static void grab_values(struct atom_value *val, int deref, struct object *obj, struct expand_data *data) - { -+ void *buf = data->content; -+ unsigned long buf_size = data->size; -+ - switch (obj->type) { - case OBJ_TAG: - grab_tag_values(val, deref, obj); -- grab_sub_body_contents(val, deref, buf, obj); -+ grab_sub_body_contents(val, deref, buf, buf_size, obj); - grab_person("tagger", val, deref, buf); - break; - case OBJ_COMMIT: - grab_commit_values(val, deref, obj); -- grab_sub_body_contents(val, deref, buf, obj); -+ grab_sub_body_contents(val, deref, buf, buf_size, obj); - grab_person("author", val, deref, buf); - grab_person("committer", val, deref, buf); +@@ ref-filter.c: static void grab_values(struct atom_value *val, int deref, struct object *obj, s break; case OBJ_TREE: /* grab_tree_values(val, deref, obj, buf, sz); */ -+ grab_sub_body_contents(val, deref, buf, buf_size, obj); ++ grab_sub_body_contents(val, deref, data); break; case OBJ_BLOB: /* grab_blob_values(val, deref, obj, buf, sz); */ -+ grab_sub_body_contents(val, deref, buf, buf_size, obj); ++ grab_sub_body_contents(val, deref, data); break; default: die("Eh? Object of type %d?", obj->type); -@@ ref-filter.c: static int get_object(struct ref_array_item *ref, int deref, struct object **obj - return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"), - oid_to_hex(&oi->oid), ref->refname); - } -- grab_values(ref->value, deref, *obj, oi->content); -+ grab_values(ref->value, deref, *obj, oi); - } - - grab_common_values(ref->value, deref, oi); @@ ref-filter.c: static int populate_value(struct ref_array_item *ref, struct strbuf *err) int deref = 0; const char *refname; -- gitgitgadget