[PATCH RFC v2 1/4] ref-filter: start using oid_object_info
Start using oid_object_info_extended(). So, if info from this function
is enough, we do not need to get and parse whole object (as it was before).
It's good for 3 reasons:
1. Some Git commands potentially will work faster.
2. It's much easier to add support for objectsize:disk and deltabase.
(I have plans to add this support further)
3. It's easier to move formatting from cat-file command to this logic
(It pretends to be unified formatting logic in the end)
Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com>
---
ref-filter.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
ref-filter.h | 21 +++++++++++++++++++++
2 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/ref-filter.c b/ref-filter.c
index 39e2744c949bb..4008351553391 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -100,6 +100,7 @@ static struct used_atom {
} u;
} *used_atom;
static int used_atom_cnt, need_tagged, need_symref;
+static struct expand_data oi_data;
/*
* Expand string, append it to strbuf *sb, then return error code ret.
@@ -267,6 +268,22 @@ static int contents_atom_parser(const struct ref_format *format, struct used_ato
return 0;
}
+static int objecttype_atom_parser(const struct ref_format *format, struct used_atom *atom,
+ const char *arg, struct strbuf *unused_err)
+{
+ oi_data.use_data = 1;
+ oi_data.info.typep = &oi_data.type;
+ return 0;
+}
+
+static int objectsize_atom_parser(const struct ref_format *format, struct used_atom *atom,
+ const char *arg, struct strbuf *unused_err)
+{
+ oi_data.use_data = 1;
+ oi_data.info.sizep = &oi_data.size;
+ return 0;
+}
+
static int objectname_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
@@ -383,9 +400,9 @@ static struct {
int (*parser)(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err);
} valid_atom[] = {
- { "refname" , FIELD_STR, refname_atom_parser },
- { "objecttype" },
- { "objectsize", FIELD_ULONG },
+ { "refname", FIELD_STR, refname_atom_parser },
+ { "objecttype", FIELD_STR, objecttype_atom_parser },
+ { "objectsize", FIELD_ULONG, objectsize_atom_parser },
{ "objectname", FIELD_STR, objectname_atom_parser },
{ "tree" },
{ "parent" },
@@ -1207,7 +1224,8 @@ static void fill_missing_values(struct atom_value *val)
*/
static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
{
- grab_common_values(val, deref, obj, buf, sz);
+ if (deref || !oi_data.use_data)
+ grab_common_values(val, deref, obj, buf, sz);
switch (obj->type) {
case OBJ_TAG:
grab_tag_values(val, deref, obj, buf, sz);
@@ -1536,6 +1554,13 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
continue;
} else if (!deref && grab_objectname(name, &ref->objectname, v, atom)) {
continue;
+ } else if (!deref && !strcmp(name, "objecttype") && oi_data.use_data) {
+ v->s = type_name(oi_data.type);
+ continue;
+ } else if (!deref && !strcmp(name, "objectsize") && oi_data.use_data) {
+ v->value = oi_data.size;
+ v->s = xstrfmt("%lu", oi_data.size);
+ continue;
} else if (!strcmp(name, "HEAD")) {
if (atom->u.head && !strcmp(ref->refname, atom->u.head))
v->s = "*";
@@ -2156,8 +2181,17 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
int (*cmp_fn)(const char *, const char *);
struct strbuf err = STRBUF_INIT;
+ oi_data.oid = a->objectname;
+ if (oi_data.use_data &&
+ oid_object_info_extended(&oi_data.oid, &oi_data.info, OBJECT_INFO_LOOKUP_REPLACE) < 0)
+ die(_("missing object %s for %s"), oid_to_hex(&a->objectname), a->refname);
if (get_ref_atom_value(a, s->atom, &va, &err))
die("%s", err.buf);
+
+ oi_data.oid = b->objectname;
+ if (oi_data.use_data &&
+ oid_object_info_extended(&oi_data.oid, &oi_data.info, OBJECT_INFO_LOOKUP_REPLACE) < 0)
+ die(_("missing object %s for %s"), oid_to_hex(&b->objectname), b->refname);
if (get_ref_atom_value(b, s->atom, &vb, &err))
die("%s", err.buf);
strbuf_release(&err);
@@ -2226,6 +2260,11 @@ int format_ref_array_item(struct ref_array_item *info,
{
const char *cp, *sp, *ep;
struct ref_formatting_state state = REF_FORMATTING_STATE_INIT;
+ oi_data.oid = info->objectname;
+ if (oi_data.use_data &&
+ oid_object_info_extended(&oi_data.oid, &oi_data.info, OBJECT_INFO_LOOKUP_REPLACE) < 0)
+ return strbuf_addf_ret(error_buf, -1, _("missing object %s for %s"),
+ oid_to_hex(&info->objectname), info->refname);
state.quote_style = format->quote_style;
push_stack_element(&state.stack);
diff --git a/ref-filter.h b/ref-filter.h
index 85c8ebc3b904e..857e8c5318a8f 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -85,6 +85,27 @@ struct ref_format {
int need_color_reset_at_eol;
};
+struct expand_data {
+ struct object_id oid;
+ enum object_type type;
+ unsigned long size;
+ off_t disk_size;
+ struct object_id delta_base_oid;
+
+ /*
+ * This object_info is set up to be passed to oid_object_info_extended.
+ * It will point to the data elements above, so you can retrieve
+ * the response from there.
+ */
+ struct object_info info;
+
+ /*
+ * This flag will be true if the requested format and options
+ * require us to call oid_object_info_extended.
+ */
+ unsigned use_data : 1;
+};
+
#define REF_FORMAT_INIT { NULL, 0, -1 }
/* Macros for checking --merged and --no-merged options */
--
https://github.com/git/git/pull/493