threads / rfc / 48514

RFC v2, 4 partsref-filter: add deltabase formatting option

Subject: [PATCH RFC v2 4/4] ref-filter: add deltabase formatting option

## tl;dr

4 messages between May 18, 2018 and May 18, 2018. Diffs are folded; open one to read it.

replies: 3people: 1as markdown or json

Olga Telezhnaya· May 18, 2018, 08:19 UTC · lore

[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(-)
Show changes to 2 files +64 −5

ref-filter.c, ref-filter.h

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
Olga Telezhnaya· May 18, 2018, 08:19 UTC · re: Olga Telezhnaya · lore

Add %(deltabase) support. It is still not working for deref: I am thinking how to support it in a more elegant way.

Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com>
---
 ref-filter.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
Show changes to ref-filter.c +12 −1
diff --git a/ref-filter.c b/ref-filter.c
index c00de58455301..989ccdb356a32 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -276,6 +276,14 @@ static int objecttype_atom_parser(const struct ref_format *format, struct used_a
 	return 0;
 }
 
+static int deltabase_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.delta_base_sha1 = oi_data.delta_base_oid.hash;
+	return 0;
+}
+
 static int objectsize_atom_parser(const struct ref_format *format, struct used_atom *atom,
 				  const char *arg, struct strbuf *err)
 {
@@ -409,6 +417,7 @@ static struct {
 	{ "objecttype", FIELD_STR, objecttype_atom_parser },
 	{ "objectsize", FIELD_ULONG, objectsize_atom_parser },
 	{ "objectname", FIELD_STR, objectname_atom_parser },
+	{ "deltabase", FIELD_STR, deltabase_atom_parser },
 	{ "tree" },
 	{ "parent" },
 	{ "numparent", FIELD_ULONG },
@@ -1572,6 +1581,9 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
 				v->s = xstrfmt("%lu", oi_data.disk_size);
 			}
 			continue;
+		} else if (!deref && !strcmp(name, "deltabase") && oi_data.use_data) {
+			v->s = xstrdup(oid_to_hex(&oi_data.delta_base_oid));
+			continue;
 		} else if (!strcmp(name, "HEAD")) {
 			if (atom->u.head && !strcmp(ref->refname, atom->u.head))
 				v->s = "*";

--
https://github.com/git/git/pull/493
Olga Telezhnaya· May 18, 2018, 08:19 UTC · re: Olga Telezhnaya · lore

[PATCH RFC v2 3/4] ref-filter: add tests for objectsize:disk

Add tests for %(objectsize:disk) atom.
Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com>
---
 t/t6300-for-each-ref.sh | 2 ++
 1 file changed, 2 insertions(+)
Show changes to t/t6300-for-each-ref.sh +2 −1
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 295d1475bde01..570bb606045d7 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -83,6 +83,7 @@ test_atom head push:strip=1 remotes/myfork/master
 test_atom head push:strip=-1 master
 test_atom head objecttype commit
 test_atom head objectsize 171
+test_atom head objectsize:disk 138
 test_atom head objectname $(git rev-parse refs/heads/master)
 test_atom head objectname:short $(git rev-parse --short refs/heads/master)
 test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master)
@@ -124,6 +125,7 @@ test_atom tag upstream ''
 test_atom tag push ''
 test_atom tag objecttype tag
 test_atom tag objectsize 154
+test_atom tag objectsize:disk 138
 test_atom tag objectname $(git rev-parse refs/tags/testtag)
 test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag)
 test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master)

--
https://github.com/git/git/pull/493
Olga Telezhnaya· May 18, 2018, 08:19 UTC · re: Olga Telezhnaya · lore

[PATCH RFC v2 2/4] ref-filter: add objectsize:disk formatting option

Add %(objectsize:disk) support. It is still not working for deref: I am thinking how to support it in a more elegant way.

Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com>
---
 ref-filter.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)
Show changes to ref-filter.c +16 −6
diff --git a/ref-filter.c b/ref-filter.c
index 4008351553391..c00de58455301 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -277,10 +277,15 @@ static int objecttype_atom_parser(const struct ref_format *format, struct used_a
 }
 
 static int objectsize_atom_parser(const struct ref_format *format, struct used_atom *atom,
-				  const char *arg, struct strbuf *unused_err)
+				  const char *arg, struct strbuf *err)
 {
+	if (!arg)
+		oi_data.info.sizep = &oi_data.size;
+	else if (!strcmp(arg, "disk"))
+		oi_data.info.disk_sizep = &oi_data.disk_size;
+	else
+		return strbuf_addf_ret(err, -1, _("unrecognized %%(objectsize) argument: %s"), arg);
 	oi_data.use_data = 1;
-	oi_data.info.sizep = &oi_data.size;
 	return 0;
 }
 
@@ -1557,9 +1562,15 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
 		} 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);
+		} else if (!deref && starts_with(name, "objectsize") && oi_data.use_data) {
+			if (!strcmp(name, "objectsize")) {
+				v->value = oi_data.size;
+				v->s = xstrfmt("%lu", oi_data.size);
+			} else {
+				/* It can be only objectsize:disk, we checked it in parser */
+				v->value = oi_data.disk_size;
+				v->s = xstrfmt("%lu", oi_data.disk_size);
+			}
 			continue;
 		} else if (!strcmp(name, "HEAD")) {
 			if (atom->u.head && !strcmp(ref->refname, atom->u.head))

--
https://github.com/git/git/pull/493

← back to recent threads