From: "ZheNing Hu via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Christian Couder" <christian.couder@gmail.com>,
"Hariom Verma" <hariom18599@gmail.com>,
"Bagas Sanjaya" <bagasdotme@gmail.com>,
"Jeff King" <peff@peff.net>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"ZheNing Hu" <adlternative@gmail.com>,
"ZheNing Hu" <adlternative@gmail.com>
Subject: [PATCH 14/15] [GSOC] cat-file: re-implement --textconv, --filters options
Date: Thu, 01 Jul 2021 16:08:12 +0000 [thread overview]
Message-ID: <3aeb4d3d3ec9dc112a19a8b4adeaf213577b4028.1625155693.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.989.git.1625155693.gitgitgadget@gmail.com>
From: ZheNing Hu <adlternative@gmail.com>
After cat-file reuses the ref-filter logic, we re-implement the
functions of --textconv and --filters options.
Add members `use_textconv` and `use_filters` in struct `ref_format`,
and use global variables `use_filters` and `use_textconv` in
`ref-filter.c`, so that we can filter the content of the object
in get_object(). Use `actual_oi` to record the real expand_data:
it may point to the original `oi` or the `act_oi` processed by
`textconv_object()` or `convert_to_working_tree()`. `grab_values()`
will grab the contents of `actual_oi` and `grab_common_values()`
to grab the contents of origin `oi`, this ensures that `%(objectsize)`
still uses the size of the unfiltered data.
In `get_object()`, we made an optimization: Firstly, get the size and
type of the object instead of directly getting the object data.
If using --textconv, after successfully obtaining the filtered object
data, an extra oid_object_info_extended() will be skipped, which can
reduce the cost of object data copy; If using --filter, the data of
the object first will be getted first, and then convert_to_working_tree()
will be used to get the filtered object data.
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Hariom Verma <hariom18599@gmail.com>
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
builtin/cat-file.c | 6 +++++
ref-filter.c | 59 ++++++++++++++++++++++++++++++++++++++++++++--
ref-filter.h | 2 ++
3 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index dc604a9879d..710085b7d72 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -380,6 +380,12 @@ static int batch_objects(struct batch_options *batch, const struct option *optio
if (batch->print_contents)
strbuf_addstr(&format, "\n%(raw)");
batch->format.format = format.buf;
+
+ if (batch->cmdmode == 'c')
+ batch->format.use_textconv = 1;
+ else if (batch->cmdmode == 'w')
+ batch->format.use_filters = 1;
+
if (verify_ref_format(&batch->format))
usage_with_options(cat_file_usage, options);
diff --git a/ref-filter.c b/ref-filter.c
index 9ca3dd5557d..427552b8108 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "parse-options.h"
@@ -84,6 +85,9 @@ static struct expand_data {
struct object_info info;
} oi, oi_deref;
+int use_filters;
+int use_textconv;
+
struct ref_to_worktree_entry {
struct hashmap_entry ent;
struct worktree *wt; /* key is wt->head_ref */
@@ -1031,6 +1035,9 @@ int verify_ref_format(struct ref_format *format)
used_atom[at].atom_type == ATOM_WORKTREEPATH)))
die(_("this command reject atom %%(%.*s)"), (int)(ep - sp - 2), sp + 2);
+ use_filters = format->use_filters;
+ use_textconv = format->use_textconv;
+
if ((format->quote_style == QUOTE_PYTHON ||
format->quote_style == QUOTE_SHELL ||
format->quote_style == QUOTE_TCL) &&
@@ -1742,10 +1749,38 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj
{
/* parse_object_buffer() will set eaten to 0 if free() will be needed */
int eaten = 1;
+ struct expand_data *actual_oi = oi;
+ struct expand_data act_oi = {0};
+
if (oi->info.contentp) {
/* We need to know that to use parse_object_buffer properly */
+ void **temp_contentp = oi->info.contentp;
+ oi->info.contentp = NULL;
oi->info.sizep = &oi->size;
oi->info.typep = &oi->type;
+
+ /* get the type and size */
+ if (oid_object_info_extended(the_repository, &oi->oid, &oi->info,
+ OBJECT_INFO_LOOKUP_REPLACE))
+ return strbuf_addf_ret(err, 1, _("%s missing"),
+ oid_to_hex(&oi->oid));
+
+ oi->info.sizep = NULL;
+ oi->info.typep = NULL;
+ oi->info.contentp = temp_contentp;
+
+ if (use_textconv && !ref->rest)
+ return strbuf_addf_ret(err, -1, _("missing path for '%s'"),
+ oid_to_hex(&act_oi.oid));
+ if (use_textconv && oi->type == OBJ_BLOB) {
+ act_oi = *oi;
+ if (textconv_object(the_repository,
+ ref->rest, 0100644, &act_oi.oid,
+ 1, (char **)(&act_oi.content), &act_oi.size)) {
+ actual_oi = &act_oi;
+ goto success;
+ }
+ }
}
if (oid_object_info_extended(the_repository, &oi->oid, &oi->info,
OBJECT_INFO_LOOKUP_REPLACE))
@@ -1755,19 +1790,39 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj
BUG("Object size is less than zero.");
if (oi->info.contentp) {
- *obj = parse_object_buffer(the_repository, &oi->oid, oi->type, oi->size, oi->content, &eaten);
+ if (use_filters && !ref->rest)
+ return strbuf_addf_ret(err, -1, _("missing path for '%s'"),
+ oid_to_hex(&oi->oid));
+ if (use_filters && oi->type == OBJ_BLOB) {
+ struct strbuf strbuf = STRBUF_INIT;
+ struct checkout_metadata meta;
+ act_oi = *oi;
+
+ init_checkout_metadata(&meta, NULL, NULL, &act_oi.oid);
+ if (!convert_to_working_tree(&the_index, ref->rest, act_oi.content, act_oi.size, &strbuf, &meta))
+ die("could not convert '%s' %s",
+ oid_to_hex(&oi->oid), ref->rest);
+ act_oi.size = strbuf.len;
+ act_oi.content = strbuf_detach(&strbuf, NULL);
+ actual_oi = &act_oi;
+ }
+
+success:
+ *obj = parse_object_buffer(the_repository, &actual_oi->oid, actual_oi->type, actual_oi->size, actual_oi->content, &eaten);
if (!*obj) {
if (!eaten)
free(oi->content);
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);
+ grab_values(ref->value, deref, *obj, actual_oi);
}
grab_common_values(ref->value, deref, oi);
if (!eaten)
free(oi->content);
+ if (actual_oi != oi)
+ free(actual_oi->content);
return 0;
}
diff --git a/ref-filter.h b/ref-filter.h
index 053980a6a42..497e3e93632 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -80,6 +80,8 @@ struct ref_format {
const char *rest;
int cat_file_mode;
int quote_style;
+ int use_textconv;
+ int use_filters;
int use_rest;
int use_color;
--
gitgitgadget
next prev parent reply other threads:[~2021-07-01 16:08 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-01 16:07 [PATCH 00/15] [GSOC] cat-file: reuse ref-filter logic ZheNing Hu via GitGitGadget
2021-07-01 16:07 ` [PATCH 01/15] [GSOC] ref-filter: add obj-type check in grab contents ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 02/15] [GSOC] ref-filter: add %(raw) atom ZheNing Hu via GitGitGadget
2021-07-02 13:22 ` Ævar Arnfjörð Bjarmason
2021-07-03 5:14 ` ZheNing Hu
2021-07-01 16:08 ` [PATCH 03/15] [GSOC] ref-filter: --format=%(raw) re-support --perl ZheNing Hu via GitGitGadget
2021-07-02 13:29 ` Ævar Arnfjörð Bjarmason
2021-07-03 5:14 ` ZheNing Hu
2021-07-01 16:08 ` [PATCH 04/15] [GSOC] ref-filter: use non-const ref_format in *_atom_parser() ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 05/15] [GSOC] ref-filter: add %(rest) atom ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 06/15] [GSOC] ref-filter: pass get_object() return value to their callers ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 07/15] [GSOC] ref-filter: introduce free_ref_array_item_value() function ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 08/15] [GSOC] ref-filter: add cat_file_mode in struct ref_format ZheNing Hu via GitGitGadget
2021-07-02 13:32 ` Ævar Arnfjörð Bjarmason
2021-07-02 19:28 ` Eric Sunshine
2021-07-02 22:11 ` Christian Couder
2021-07-03 5:55 ` ZheNing Hu
2021-07-05 7:17 ` Ævar Arnfjörð Bjarmason
2021-07-01 16:08 ` [PATCH 09/15] [GSOC] ref-filter: modify the error message and value in get_object ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 10/15] [GSOC] cat-file: add has_object_file() check ZheNing Hu via GitGitGadget
2021-07-02 13:34 ` Ævar Arnfjörð Bjarmason
2021-07-03 5:50 ` ZheNing Hu
2021-07-01 16:08 ` [PATCH 11/15] [GSOC] cat-file: change batch_objects parameter name ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` [PATCH 12/15] [GSOC] cat-file: reuse ref-filter logic ZheNing Hu via GitGitGadget
2021-07-02 13:36 ` Ævar Arnfjörð Bjarmason
2021-07-02 13:45 ` Christian Couder
2021-07-03 11:45 ` ZheNing Hu
2021-07-03 13:37 ` Ævar Arnfjörð Bjarmason
2021-07-04 11:10 ` ZheNing Hu
2021-07-05 7:18 ` Ævar Arnfjörð Bjarmason
2021-07-03 14:17 ` ZheNing Hu
2021-07-01 16:08 ` [PATCH 13/15] [GSOC] cat-file: reuse err buf in batch_object_write() ZheNing Hu via GitGitGadget
2021-07-01 16:08 ` ZheNing Hu via GitGitGadget [this message]
2021-07-01 19:55 ` [PATCH 14/15] [GSOC] cat-file: re-implement --textconv, --filters options Junio C Hamano
2021-07-01 20:11 ` Junio C Hamano
2021-07-02 12:46 ` ZheNing Hu
2021-07-02 15:27 ` Junio C Hamano
2021-07-03 6:17 ` ZheNing Hu
2021-07-01 16:08 ` [PATCH 15/15] [GSOC] ref-filter: remove grab_oid() function ZheNing Hu via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3aeb4d3d3ec9dc112a19a8b4adeaf213577b4028.1625155693.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=adlternative@gmail.com \
--cc=avarab@gmail.com \
--cc=bagasdotme@gmail.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hariom18599@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).