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>,
Karthik Nayak <karthik.188@gmail.com>,
Felipe Contreras <felipe.contreras@gmail.com>,
Bagas Sanjaya <bagasdotme@gmail.com>, Jeff King <peff@peff.net>,
ZheNing Hu <adlternative@gmail.com>,
ZheNing Hu <adlternative@gmail.com>
Subject: [PATCH 2/2] [GSOC] ref-filter: add %(header) atom
Date: Thu, 27 May 2021 14:43:22 +0000 [thread overview]
Message-ID: <aa6d73f3e526f416ee1e4e332e9ca3119efba0e8.1622126603.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.963.git.1622126603.gitgitgadget@gmail.com>
From: ZheNing Hu <adlternative@gmail.com>
Add new formatting option `%(header)`, which will print the
the structured header part of the raw object data.
In the storage layout of an object: blob and tree only
contains raw data; commit and tag raw data contains two part:
header and contents. The header of tag contains "object OOO",
"type TTT", "tag AAA", "tagger GGG"; The header of commit
contains "tree RRR", "parent PPP", "author UUU", "committer CCC".
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
Documentation/git-for-each-ref.txt | 7 +++++
ref-filter.c | 26 +++++++++++++++++
t/t6300-for-each-ref.sh | 45 ++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+)
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index f6ae751fd256..7827e48cde75 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -249,6 +249,13 @@ Note that `--format=%(raw)` should not combine with `--python`, `--shell`, `--tc
`--perl` because if our binary raw data is passed to a variable in the host language,
the host languages may cause escape errors.
+The structured header part of the raw data in a commit or a tag object is `header`,
+it composed of "tree XXX", "parent YYY", etc lines in commits, or composed of
+"object OOO", "type TTT", etc lines in tags.
+
+header:size::
+ The header size of the object.
+
The message in a commit or a tag object is `contents`, from which
`contents:<part>` can be used to extract various parts out of:
diff --git a/ref-filter.c b/ref-filter.c
index c2abf5da7006..2f426830f562 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -141,6 +141,9 @@ static struct used_atom {
struct {
enum { RAW_BARE, RAW_LENGTH } option;
} raw_data;
+ struct {
+ enum { H_BARE, H_LENGTH } option;
+ } header;
struct {
cmp_status cmp_status;
const char *str;
@@ -385,6 +388,18 @@ static int raw_atom_parser(const struct ref_format *format, struct used_atom *at
return 0;
}
+static int header_atom_parser(const struct ref_format *format, struct used_atom *atom,
+ const char *arg, struct strbuf *err)
+{
+ if (!arg)
+ atom->u.header.option = H_BARE;
+ else if (!strcmp(arg, "size"))
+ atom->u.header.option = H_LENGTH;
+ else
+ return strbuf_addf_ret(err, -1, _("unrecognized %%(header) argument: %s"), arg);
+ return 0;
+}
+
static int oid_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
@@ -546,6 +561,7 @@ static struct {
{ "trailers", SOURCE_OBJ, FIELD_STR, trailers_atom_parser },
{ "contents", SOURCE_OBJ, FIELD_STR, contents_atom_parser },
{ "raw", SOURCE_OBJ, FIELD_STR, raw_atom_parser },
+ { "header", SOURCE_OBJ, FIELD_STR, header_atom_parser },
{ "upstream", SOURCE_NONE, FIELD_STR, remote_ref_atom_parser },
{ "push", SOURCE_NONE, FIELD_STR, remote_ref_atom_parser },
{ "symref", SOURCE_NONE, FIELD_STR, refname_atom_parser },
@@ -1362,6 +1378,7 @@ static void grab_raw_data(struct atom_value *val, int deref, void *buf, unsigned
if ((obj->type != OBJ_TAG &&
obj->type != OBJ_COMMIT) ||
(strcmp(name, "body") &&
+ !starts_with(name, "header") &&
!starts_with(name, "subject") &&
!starts_with(name, "trailers") &&
!starts_with(name, "contents")))
@@ -1372,6 +1389,15 @@ static void grab_raw_data(struct atom_value *val, int deref, void *buf, unsigned
&bodypos, &bodylen, &nonsiglen,
&sigpos, &siglen);
+ if (starts_with(name, "header")) {
+ size_t header_len = subpos - (const char *)buf - 1;
+ if (atom->u.header.option == H_BARE) {
+ v->s = xmemdupz(buf, header_len);
+ } else if (atom->u.header.option == H_LENGTH)
+ v->s = xstrfmt("%"PRIuMAX, (uintmax_t)header_len);
+ continue;
+ }
+
if (atom->u.contents.option == C_SUB)
v->s = copy_subject(subpos, sublen);
else if (atom->u.contents.option == C_SUB_SANITIZE) {
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 07de4a84d70b..11fc8fc53649 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -232,6 +232,35 @@ test_expect_success 'basic atom: refs/tags/testtag *raw' '
test_cmp expected.clean actual.clean
'
+test_expect_success 'basic atom: refs/tags/testtag header' '
+ cat >expected <<-EOF &&
+ object ea122842f48be4afb2d1fc6a4b96c05885ab7463
+ type commit
+ tag testtag
+ tagger C O Mitter <committer@example.com> 1151968725 +0200
+
+ EOF
+ git for-each-ref --format="%(header)" refs/tags/testtag >actual &&
+ test_cmp expected actual &&
+ echo "131" >expected &&
+ git for-each-ref --format="%(header:size)" refs/tags/testtag >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'basic atom: refs/heads/main header' '
+ cat >expected <<-EOF &&
+ tree 8039ce043250c402d62ca312e9596e42ce1c7bb0
+ author A U Thor <author@example.com> 1151968724 +0200
+ committer C O Mitter <committer@example.com> 1151968723 +0200
+
+ EOF
+ git for-each-ref --format="%(header)" refs/heads/main >actual &&
+ test_cmp expected actual &&
+ echo "162" >expected &&
+ git for-each-ref --format="%(header:size)" refs/heads/main >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'Check invalid atoms names are errors' '
test_must_fail git for-each-ref --format="%(INVALID)" refs/heads
'
@@ -768,6 +797,14 @@ test_expect_success 'basic atom: refs/mytrees/first raw' '
test_cmp expected actual
'
+test_expect_success 'basic atom: refs/mytrees/first header' '
+ echo "" >expected &&
+ git for-each-ref --format="%(header)" refs/mytrees/first >actual &&
+ test_cmp expected actual &&
+ git for-each-ref --format="%(header:size)" refs/mytrees/first >actual &&
+ test_cmp expected actual
+'
+
test_atom refs/myblobs/first subject ""
test_atom refs/myblobs/first contents:subject ""
test_atom refs/myblobs/first body ""
@@ -785,6 +822,14 @@ test_expect_success 'basic atom: refs/myblobs/first raw' '
test_cmp expected actual
'
+test_expect_success 'basic atom: refs/myblobs/first header' '
+ echo "" >expected &&
+ git for-each-ref --format="%(header)" refs/myblobs/first >actual &&
+ test_cmp expected actual &&
+ git for-each-ref --format="%(header:size)" refs/myblobs/first >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'set up refs pointing to binary blob' '
printf "%b" "a\0b\0c" >blob1 &&
printf "%b" "a\0c\0b" >blob2 &&
--
gitgitgadget
next prev parent reply other threads:[~2021-05-27 14:43 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-27 14:43 [PATCH 0/2] [GSOC] ref-filter: add %(raw) atom ZheNing Hu via GitGitGadget
2021-05-27 14:43 ` [PATCH 1/2] " ZheNing Hu via GitGitGadget
2021-05-27 16:36 ` Felipe Contreras
2021-05-28 13:02 ` ZheNing Hu
2021-05-28 16:30 ` Felipe Contreras
2021-05-30 5:37 ` ZheNing Hu
2021-05-29 13:23 ` Phillip Wood
2021-05-29 15:24 ` Felipe Contreras
2021-05-29 17:23 ` Phillip Wood
2021-05-30 6:29 ` ZheNing Hu
2021-05-30 13:05 ` Phillip Wood
2021-05-31 14:15 ` ZheNing Hu
2021-05-31 15:35 ` Felipe Contreras
2021-05-30 6:26 ` ZheNing Hu
2021-05-30 13:02 ` Phillip Wood
2021-05-28 3:03 ` Junio C Hamano
2021-05-28 15:04 ` ZheNing Hu
2021-05-28 16:38 ` Felipe Contreras
2021-05-30 8:11 ` ZheNing Hu
2021-05-27 14:43 ` ZheNing Hu via GitGitGadget [this message]
2021-05-27 16:37 ` [PATCH 2/2] [GSOC] ref-filter: add %(header) atom Felipe Contreras
2021-05-28 3:06 ` Junio C Hamano
2021-05-28 4:36 ` Junio C Hamano
2021-05-28 15:19 ` ZheNing Hu
2021-05-27 15:39 ` [PATCH 0/2] [GSOC] ref-filter: add %(raw) atom Felipe Contreras
2021-05-30 13:01 ` [PATCH v2 " ZheNing Hu via GitGitGadget
2021-05-30 13:01 ` [PATCH v2 1/2] [GSOC] ref-filter: add obj-type check in grab contents ZheNing Hu via GitGitGadget
2021-05-31 5:34 ` Junio C Hamano
2021-05-30 13:01 ` [PATCH v2 2/2] [GSOC] ref-filter: add %(raw) atom ZheNing Hu via GitGitGadget
2021-05-31 0:44 ` Junio C Hamano
2021-05-31 14:35 ` ZheNing Hu
2021-06-01 9:54 ` Junio C Hamano
2021-06-01 11:05 ` ZheNing Hu
2021-05-31 4:04 ` Junio C Hamano
2021-05-31 14:40 ` ZheNing Hu
2021-06-01 8:54 ` Junio C Hamano
2021-06-01 11:00 ` ZheNing Hu
2021-06-01 13:48 ` Johannes Schindelin
2021-05-31 4:10 ` Junio C Hamano
2021-05-31 15:41 ` Felipe Contreras
2021-06-01 10:37 ` ZheNing Hu
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aa6d73f3e526f416ee1e4e332e9ca3119efba0e8.1622126603.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=adlternative@gmail.com \
--cc=bagasdotme@gmail.com \
--cc=christian.couder@gmail.com \
--cc=felipe.contreras@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hariom18599@gmail.com \
--cc=karthik.188@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.
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 NNTP newsgroup(s).