{"thread":{"id":"55585","subject":"[PATCH] [GSOC] ref-filter: add %(notes) format atom","startedAt":"2021-04-29T10:24:46Z","lastAt":"2021-05-03T13:25:38Z","messageCount":5,"participants":["ZheNing Hu via GitGitGadget","René Scharfe","ZheNing Hu","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"423259","messageId":"pull.944.git.1619691880696.gitgitgadget@gmail.com","threadId":"55585","inReplyTo":null,"subject":"[PATCH] [GSOC] ref-filter: add %(notes) format atom","fromName":"ZheNing Hu via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-04-29T10:24:40Z","receivedAt":"2021-04-29T10:24:46Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\nNote that `--pretty=\"%N\"` can view notes related\nto the commit. So add `%(notes)` to ref-filter\nseem is a good choice. This atom `%(notes)` view\nthe notes associated with the ref, and support\ndereference.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    [GSOC] ref-filter: add %(notes) format atom\n    \n    An important step in the GSOC project Use ref-filter formats in git\n    cat-file is to integrate different format atoms into the ref-filter.\n    Olga and Hariom have also made a lot of efforts in this area.\n    \n    Currently, I noticed that there may be some format atoms in \"pretty.c\"\n    that have not been migrated to ref-filter, such as --pretty=\"%N\",\n    --pretty=\"%(describe)\".\n    \n    So in this patch, I tried to migrate --pretty=%N to --format=%(notes).\n    \n    Hope this will be hopeful !!!\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-944%2Fadlternative%2Fformat-notes-atom-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-944/adlternative/format-notes-atom-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/944\n\n Documentation/git-for-each-ref.txt |  4 ++++\n ref-filter.c                       | 31 ++++++++++++++++++++++++++++--\n t/t6300-for-each-ref.sh            | 10 ++++++++++\n 3 files changed, 43 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex 2ae2478de706..07f037a16e13 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -139,6 +139,9 @@ deltabase::\n \tgiven object, if it is stored as a delta.  Otherwise it\n \texpands to the null object name (all zeroes).\n \n+notes::\n+\tThe notes associated with the ref.\n+\n upstream::\n \tThe name of a local ref which can be considered ``upstream''\n \tfrom the displayed ref. Respects `:short`, `:lstrip` and\n@@ -302,6 +305,7 @@ git for-each-ref --count=3 --sort='-*authordate' \\\n Subject: %(*subject)\n Date: %(*authordate)\n Ref: %(*refname)\n+Notes: %(*notes)\n \n %(*body)\n ' 'refs/tags'\ndiff --git a/ref-filter.c b/ref-filter.c\nindex a0adb4551d87..42a5608a3056 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -23,6 +23,7 @@\n #include \"worktree.h\"\n #include \"hashmap.h\"\n #include \"strvec.h\"\n+#include \"run-command.h\"\n \n static struct ref_msg {\n \tconst char *gone;\n@@ -506,6 +507,7 @@ static struct {\n \t{ \"objectsize\", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },\n \t{ \"objectname\", SOURCE_OTHER, FIELD_STR, oid_atom_parser },\n \t{ \"deltabase\", SOURCE_OTHER, FIELD_STR, deltabase_atom_parser },\n+\t{ \"notes\", SOURCE_OTHER, FIELD_STR },\n \t{ \"tree\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n \t{ \"parent\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n \t{ \"numparent\", SOURCE_OBJ, FIELD_ULONG },\n@@ -953,6 +955,24 @@ static int grab_oid(const char *name, const char *field, const struct object_id\n \treturn 0;\n }\n \n+static int grab_notes(const struct object_id *oid, struct atom_value *v)\n+{\n+\tstruct child_process cmd = CHILD_PROCESS_INIT;\n+\tstruct strbuf out = STRBUF_INIT;\n+\tstruct strbuf err = STRBUF_INIT;\n+\tconst char *args[] = { \"notes\", \"show\", NULL };\n+\tint ret;\n+\n+\tcmd.git_cmd = 1;\n+\tstrvec_pushv(&cmd.args, args);\n+\tstrvec_push(&cmd.args, oid_to_hex(oid));\n+\tret = pipe_command(&cmd, NULL, 0, &out, 0, &err, 0);\n+\tstrbuf_trim_trailing_newline(&out);\n+\tv->s = strbuf_detach(&out, NULL);\n+\tstrbuf_release(&err);\n+\treturn ret;\n+}\n+\n /* See grab_values */\n static void grab_common_values(struct atom_value *val, int deref, struct expand_data *oi)\n {\n@@ -975,8 +995,12 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_\n \t\t\tv->s = xstrfmt(\"%\"PRIuMAX , (uintmax_t)oi->size);\n \t\t} else if (!strcmp(name, \"deltabase\"))\n \t\t\tv->s = xstrdup(oid_to_hex(&oi->delta_base_oid));\n-\t\telse if (deref)\n-\t\t\tgrab_oid(name, \"objectname\", &oi->oid, v, &used_atom[i]);\n+\t\telse if (deref) {\n+\t\t\tif (!strcmp(name, \"notes\"))\n+\t\t\t\tgrab_notes(&oi->oid, v);\n+\t\t\telse\n+\t\t\t\tgrab_oid(name, \"objectname\", &oi->oid, v, &used_atom[i]);\n+\t\t}\n \t}\n }\n \n@@ -1767,6 +1791,9 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)\n \t\t\tcontinue;\n \t\t} else if (!deref && grab_oid(name, \"objectname\", &ref->objectname, v, atom)) {\n \t\t\tcontinue;\n+\t\t} else if (!deref && !strcmp(name, \"notes\")) {\n+\t\t\tgrab_notes(&ref->objectname, v);\n+\t\t\tcontinue;\n \t\t} else if (!strcmp(name, \"HEAD\")) {\n \t\t\tif (atom->u.head && !strcmp(ref->refname, atom->u.head))\n \t\t\t\tv->s = xstrdup(\"*\");\ndiff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh\nindex 9e0214076b4d..61cdbeb696ff 100755\n--- a/t/t6300-for-each-ref.sh\n+++ b/t/t6300-for-each-ref.sh\n@@ -32,8 +32,10 @@ test_expect_success setup '\n \tgit add one &&\n \tgit commit -m \"Initial\" &&\n \tgit branch -M main &&\n+\tgit notes add -m \"commit-notes\" HEAD &&\n \tsetdate_and_increment &&\n \tgit tag -a -m \"Tagging at $datestamp\" testtag &&\n+\tgit notes add -m \"tag-notes\" testtag &&\n \tgit update-ref refs/remotes/origin/main main &&\n \tgit remote add origin nowhere &&\n \tgit config branch.main.remote origin &&\n@@ -162,6 +164,7 @@ test_atom head contents:signature ''\n test_atom head contents 'Initial\n '\n test_atom head HEAD '*'\n+test_atom head notes $(git notes show refs/heads/main)\n \n test_atom tag refname refs/tags/testtag\n test_atom tag refname:short testtag\n@@ -220,6 +223,8 @@ test_atom tag contents:signature ''\n test_atom tag contents 'Tagging at 1151968727\n '\n test_atom tag HEAD ' '\n+test_atom tag notes $(git notes show refs/tags/testtag)\n+test_atom tag \"*notes\" $(git notes show refs/heads/main)\n \n test_expect_success 'Check invalid atoms names are errors' '\n \ttest_must_fail git for-each-ref --format=\"%(INVALID)\" refs/heads\n@@ -380,6 +385,7 @@ test_expect_success 'exercise strftime with odd fields' '\n \n cat >expected <<\\EOF\n refs/heads/main\n+refs/notes/commits\n refs/remotes/origin/main\n refs/tags/testtag\n EOF\n@@ -393,6 +399,7 @@ test_expect_success 'Verify ascending sort' '\n cat >expected <<\\EOF\n refs/tags/testtag\n refs/remotes/origin/main\n+refs/notes/commits\n refs/heads/main\n EOF\n \n@@ -429,6 +436,7 @@ test_expect_success 'exercise glob patterns with prefixes' '\n \n cat >expected <<\\EOF\n 'refs/heads/main'\n+'refs/notes/commits'\n 'refs/remotes/origin/main'\n 'refs/tags/testtag'\n EOF\n@@ -450,6 +458,7 @@ test_expect_success 'Quoting style: python' '\n \n cat >expected <<\\EOF\n \"refs/heads/main\"\n+\"refs/notes/commits\"\n \"refs/remotes/origin/main\"\n \"refs/tags/testtag\"\n EOF\n@@ -509,6 +518,7 @@ test_expect_success 'Check for invalid refname format' '\n test_expect_success 'set up color tests' '\n \tcat >expected.color <<-EOF &&\n \t$(git rev-parse --short refs/heads/main) <GREEN>main<RESET>\n+\t$(git rev-parse --short refs/notes/commits) <GREEN>notes/commits<RESET>\n \t$(git rev-parse --short refs/remotes/myfork/main) <GREEN>myfork/main<RESET>\n \t$(git rev-parse --short refs/remotes/origin/main) <GREEN>origin/main<RESET>\n \t$(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET>\n\nbase-commit: 311531c9de557d25ac087c1637818bd2aad6eb3a\n-- \ngitgitgadget\n"},{"id":"423424","messageId":"38083c1b-f92b-7624-67b7-3a5dcf213d79@web.de","threadId":"55585","inReplyTo":"pull.944.git.1619691880696.gitgitgadget@gmail.com","subject":"Re: [PATCH] [GSOC] ref-filter: add %(notes) format atom","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2021-05-01T19:21:20Z","receivedAt":"2021-05-01T19:21:39Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 29.04.21 um 12:24 schrieb ZheNing Hu via GitGitGadget:\n> From: ZheNing Hu <adlternative@gmail.com>\n>\n> Note that `--pretty=\"%N\"` can view notes related\n> to the commit. So add `%(notes)` to ref-filter\n> seem is a good choice. This atom `%(notes)` view\n> the notes associated with the ref, and support\n> dereference.\n\nI can't judge the usefulness of this feature because I don't use notes.\n\n> Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n> ---\n>     [GSOC] ref-filter: add %(notes) format atom\n>\n>     An important step in the GSOC project Use ref-filter formats in git\n>     cat-file is to integrate different format atoms into the ref-filter.\n>     Olga and Hariom have also made a lot of efforts in this area.\n\nThis is done to replace the custom format parser in git cat-file with\nref-filter in order to reduce code duplication, right?\n\n>     Currently, I noticed that there may be some format atoms in \"pretty.c\"\n>     that have not been migrated to ref-filter, such as --pretty=\"%N\",\n>     --pretty=\"%(describe)\".\n\ngit cat-file doesn't support pretty format atoms, so I'm not sure I see\nthe connection here.\n\n>     So in this patch, I tried to migrate --pretty=%N to --format=%(notes).\n>\n>     Hope this will be hopeful !!!\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-944%2Fadlternative%2Fformat-notes-atom-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-944/adlternative/format-notes-atom-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/944\n>\n>  Documentation/git-for-each-ref.txt |  4 ++++\n>  ref-filter.c                       | 31 ++++++++++++++++++++++++++++--\n>  t/t6300-for-each-ref.sh            | 10 ++++++++++\n>  3 files changed, 43 insertions(+), 2 deletions(-)\n>\n> diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\n> index 2ae2478de706..07f037a16e13 100644\n> --- a/Documentation/git-for-each-ref.txt\n> +++ b/Documentation/git-for-each-ref.txt\n> @@ -139,6 +139,9 @@ deltabase::\n>  \tgiven object, if it is stored as a delta.  Otherwise it\n>  \texpands to the null object name (all zeroes).\n>\n> +notes::\n> +\tThe notes associated with the ref.\n> +\n>  upstream::\n>  \tThe name of a local ref which can be considered ``upstream''\n>  \tfrom the displayed ref. Respects `:short`, `:lstrip` and\n> @@ -302,6 +305,7 @@ git for-each-ref --count=3 --sort='-*authordate' \\\n>  Subject: %(*subject)\n>  Date: %(*authordate)\n>  Ref: %(*refname)\n> +Notes: %(*notes)\n>\n>  %(*body)\n>  ' 'refs/tags'\n> diff --git a/ref-filter.c b/ref-filter.c\n> index a0adb4551d87..42a5608a3056 100644\n> --- a/ref-filter.c\n> +++ b/ref-filter.c\n> @@ -23,6 +23,7 @@\n>  #include \"worktree.h\"\n>  #include \"hashmap.h\"\n>  #include \"strvec.h\"\n> +#include \"run-command.h\"\n>\n>  static struct ref_msg {\n>  \tconst char *gone;\n> @@ -506,6 +507,7 @@ static struct {\n>  \t{ \"objectsize\", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },\n>  \t{ \"objectname\", SOURCE_OTHER, FIELD_STR, oid_atom_parser },\n>  \t{ \"deltabase\", SOURCE_OTHER, FIELD_STR, deltabase_atom_parser },\n> +\t{ \"notes\", SOURCE_OTHER, FIELD_STR },\n>  \t{ \"tree\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n>  \t{ \"parent\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n>  \t{ \"numparent\", SOURCE_OBJ, FIELD_ULONG },\n> @@ -953,6 +955,24 @@ static int grab_oid(const char *name, const char *field, const struct object_id\n>  \treturn 0;\n>  }\n>\n> +static int grab_notes(const struct object_id *oid, struct atom_value *v)\n> +{\n> +\tstruct child_process cmd = CHILD_PROCESS_INIT;\n> +\tstruct strbuf out = STRBUF_INIT;\n> +\tstruct strbuf err = STRBUF_INIT;\n> +\tconst char *args[] = { \"notes\", \"show\", NULL };\n> +\tint ret;\n> +\n> +\tcmd.git_cmd = 1;\n> +\tstrvec_pushv(&cmd.args, args);\n> +\tstrvec_push(&cmd.args, oid_to_hex(oid));\n> +\tret = pipe_command(&cmd, NULL, 0, &out, 0, &err, 0);\n\nNice prototype.  Is it possible to avoid the overhead of calling git\nnotes as an external process by calling load_display_notes() once at\nparse time and format_display_notes() for each item?  Would it cause\nconflicts for code that uses ref-filter and handles notes already?\n\n> +\tstrbuf_trim_trailing_newline(&out);\n> +\tv->s = strbuf_detach(&out, NULL);\n> +\tstrbuf_release(&err);\n> +\treturn ret;\n> +}\n> +\n>  /* See grab_values */\n>  static void grab_common_values(struct atom_value *val, int deref, struct expand_data *oi)\n>  {\n> @@ -975,8 +995,12 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_\n>  \t\t\tv->s = xstrfmt(\"%\"PRIuMAX , (uintmax_t)oi->size);\n>  \t\t} else if (!strcmp(name, \"deltabase\"))\n>  \t\t\tv->s = xstrdup(oid_to_hex(&oi->delta_base_oid));\n> -\t\telse if (deref)\n> -\t\t\tgrab_oid(name, \"objectname\", &oi->oid, v, &used_atom[i]);\n> +\t\telse if (deref) {\n> +\t\t\tif (!strcmp(name, \"notes\"))\n> +\t\t\t\tgrab_notes(&oi->oid, v);\n> +\t\t\telse\n> +\t\t\t\tgrab_oid(name, \"objectname\", &oi->oid, v, &used_atom[i]);\n> +\t\t}\n>  \t}\n>  }\n>\n> @@ -1767,6 +1791,9 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)\n>  \t\t\tcontinue;\n>  \t\t} else if (!deref && grab_oid(name, \"objectname\", &ref->objectname, v, atom)) {\n>  \t\t\tcontinue;\n> +\t\t} else if (!deref && !strcmp(name, \"notes\")) {\n> +\t\t\tgrab_notes(&ref->objectname, v);\n> +\t\t\tcontinue;\n>  \t\t} else if (!strcmp(name, \"HEAD\")) {\n>  \t\t\tif (atom->u.head && !strcmp(ref->refname, atom->u.head))\n>  \t\t\t\tv->s = xstrdup(\"*\");\n"},{"id":"423435","messageId":"CAOLTT8TGaVxxHJRF_-Dq0Gnd50_H-80C6zPhjQAQruiO59qw2A@mail.gmail.com","threadId":"55585","inReplyTo":"38083c1b-f92b-7624-67b7-3a5dcf213d79@web.de","subject":"Re: [PATCH] [GSOC] ref-filter: add %(notes) format atom","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2021-05-02T06:12:09Z","receivedAt":"2021-05-02T06:12:24Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"René Scharfe <l.s.r@web.de> 于2021年5月2日周日 上午3:21写道：\n>\n> Am 29.04.21 um 12:24 schrieb ZheNing Hu via GitGitGadget:\n> > From: ZheNing Hu <adlternative@gmail.com>\n> >\n> > Note that `--pretty=\"%N\"` can view notes related\n> > to the commit. So add `%(notes)` to ref-filter\n> > seem is a good choice. This atom `%(notes)` view\n> > the notes associated with the ref, and support\n> > dereference.\n>\n> I can't judge the usefulness of this feature because I don't use notes.\n>\n> > Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n> > ---\n> >     [GSOC] ref-filter: add %(notes) format atom\n> >\n> >     An important step in the GSOC project Use ref-filter formats in git\n> >     cat-file is to integrate different format atoms into the ref-filter.\n> >     Olga and Hariom have also made a lot of efforts in this area.\n>\n> This is done to replace the custom format parser in git cat-file with\n> ref-filter in order to reduce code duplication, right?\n>\n> >     Currently, I noticed that there may be some format atoms in \"pretty.c\"\n> >     that have not been migrated to ref-filter, such as --pretty=\"%N\",\n> >     --pretty=\"%(describe)\".\n>\n> git cat-file doesn't support pretty format atoms, so I'm not sure I see\n> the connection here.\n>\n\nAt present, `git cat-file --batch`, `git log --pretty`, and `git\nfor-each-ref --format`\nlack consistency.\n\nThe ambition of this project is to unify these different formats\n\"%aN\",\"%(authorname)\"\nthrough an interface, maybe it's `ref-filter` or maybe a new one.\n\nIt is estimated that many places in need to be replaced and rebuilt,\nand it not just to\nreduce code duplication.\n\nNote that `cat-file --batch` should be a superset of `ref-filter` and\n`--pretty`, because\nit supports all objects, while `ref-filter` only supports \"commit\" and\n\"tag\" two kinds\nof objects, and `--pretty` only supports \"commit\" one kind of object.\n\nSo it may be reasonable to provide `%(notes)` to \"commit\",\"tag\"\nobjects in `cat-file --batch`\nin the future, now integrate them into ref-filter firstly.\n\n> >     So in this patch, I tried to migrate --pretty=%N to --format=%(notes).\n> >\n> >     Hope this will be hopeful !!!\n> >\n> > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-944%2Fadlternative%2Fformat-notes-atom-v1\n> > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-944/adlternative/format-notes-atom-v1\n> > Pull-Request: https://github.com/gitgitgadget/git/pull/944\n> >\n> >  Documentation/git-for-each-ref.txt |  4 ++++\n> >  ref-filter.c                       | 31 ++++++++++++++++++++++++++++--\n> >  t/t6300-for-each-ref.sh            | 10 ++++++++++\n> >  3 files changed, 43 insertions(+), 2 deletions(-)\n> >\n> > diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\n> > index 2ae2478de706..07f037a16e13 100644\n> > --- a/Documentation/git-for-each-ref.txt\n> > +++ b/Documentation/git-for-each-ref.txt\n> > @@ -139,6 +139,9 @@ deltabase::\n> >       given object, if it is stored as a delta.  Otherwise it\n> >       expands to the null object name (all zeroes).\n> >\n> > +notes::\n> > +     The notes associated with the ref.\n> > +\n> >  upstream::\n> >       The name of a local ref which can be considered ``upstream''\n> >       from the displayed ref. Respects `:short`, `:lstrip` and\n> > @@ -302,6 +305,7 @@ git for-each-ref --count=3 --sort='-*authordate' \\\n> >  Subject: %(*subject)\n> >  Date: %(*authordate)\n> >  Ref: %(*refname)\n> > +Notes: %(*notes)\n> >\n> >  %(*body)\n> >  ' 'refs/tags'\n> > diff --git a/ref-filter.c b/ref-filter.c\n> > index a0adb4551d87..42a5608a3056 100644\n> > --- a/ref-filter.c\n> > +++ b/ref-filter.c\n> > @@ -23,6 +23,7 @@\n> >  #include \"worktree.h\"\n> >  #include \"hashmap.h\"\n> >  #include \"strvec.h\"\n> > +#include \"run-command.h\"\n> >\n> >  static struct ref_msg {\n> >       const char *gone;\n> > @@ -506,6 +507,7 @@ static struct {\n> >       { \"objectsize\", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },\n> >       { \"objectname\", SOURCE_OTHER, FIELD_STR, oid_atom_parser },\n> >       { \"deltabase\", SOURCE_OTHER, FIELD_STR, deltabase_atom_parser },\n> > +     { \"notes\", SOURCE_OTHER, FIELD_STR },\n> >       { \"tree\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n> >       { \"parent\", SOURCE_OBJ, FIELD_STR, oid_atom_parser },\n> >       { \"numparent\", SOURCE_OBJ, FIELD_ULONG },\n> > @@ -953,6 +955,24 @@ static int grab_oid(const char *name, const char *field, const struct object_id\n> >       return 0;\n> >  }\n> >\n> > +static int grab_notes(const struct object_id *oid, struct atom_value *v)\n> > +{\n> > +     struct child_process cmd = CHILD_PROCESS_INIT;\n> > +     struct strbuf out = STRBUF_INIT;\n> > +     struct strbuf err = STRBUF_INIT;\n> > +     const char *args[] = { \"notes\", \"show\", NULL };\n> > +     int ret;\n> > +\n> > +     cmd.git_cmd = 1;\n> > +     strvec_pushv(&cmd.args, args);\n> > +     strvec_push(&cmd.args, oid_to_hex(oid));\n> > +     ret = pipe_command(&cmd, NULL, 0, &out, 0, &err, 0);\n>\n> Nice prototype.  Is it possible to avoid the overhead of calling git\n> notes as an external process by calling load_display_notes() once at\n> parse time and format_display_notes() for each item?  Would it cause\n> conflicts for code that uses ref-filter and handles notes already?\n>\n\nThis sounds feasible, I will try if it can work.\n\nThanks!\n--\nZheNing Hu\n"},{"id":"423456","messageId":"xmqqsg34a5j8.fsf@gitster.g","threadId":"55585","inReplyTo":"CAOLTT8TGaVxxHJRF_-Dq0Gnd50_H-80C6zPhjQAQruiO59qw2A@mail.gmail.com","subject":"Re: [PATCH] [GSOC] ref-filter: add %(notes) format atom","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-05-03T02:56:59Z","receivedAt":"2021-05-03T02:57:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n> Note that `cat-file --batch` should be a superset of `ref-filter` and\n> `--pretty`, because\n> it supports all objects, while `ref-filter` only supports \"commit\" and\n> \"tag\" two kinds\n> of objects, and `--pretty` only supports \"commit\" one kind of object.\n\nWhat?  A ref can point at any kind of objects, not necessarily\ncommits and tags.  %(objectname), %(objecttype), etc. obviously\nare applicable to any type of object.\n\nAnother thing worth noting is that ref-filter needs to deal with\ntraits that are not tied to any particular object, but to the ref\nitself, like who its upstream is and where it would be pushed to.\n\n> So it may be reasonable to provide `%(notes)` to \"commit\",\"tag\"\n> objects in `cat-file --batch`\n> in the future, now integrate them into ref-filter firstly.\n\nAnd you can attach notes to objects of any type, not limited to\ncommits and tags.\n\n>> >     So in this patch, I tried to migrate --pretty=%N to --format=%(notes).\n\nWhat do you mean by \"migrate\"?  Are you making both available?\n\n>> > diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\n>> > index 2ae2478de706..07f037a16e13 100644\n>> > --- a/Documentation/git-for-each-ref.txt\n>> > +++ b/Documentation/git-for-each-ref.txt\n>> > @@ -139,6 +139,9 @@ deltabase::\n>> >       given object, if it is stored as a delta.  Otherwise it\n>> >       expands to the null object name (all zeroes).\n>> >\n>> > +notes::\n>> > +     The notes associated with the ref.\n\n\"The notes associated with the object pointed at by the ref\".\n\nA note is never associated with a ref.  It can only associated with\nan object.\n\nIf we are going to have %(notes), it may be natural to desire\ngrabbing notes for the given object from specified notes ref, e.g.\n\n    git for-each-ref --format=\"%(notes:amlog) %(subject)\" zh/pretty-date-human\n\nmay want to give the same kind of information as\n\n    git show -s --format='%N %s' --notes=amlog zh/pretty-date-human\n\nThe underlying notes machinery however may not be prepared to work\nwith more than one notes tree at the same time, so\n\n    git for-each-ref --format=\"%(notes) %(subject)\" --notes=amlog zh/pretty-date-human\n\nmight be a better syntax, as --format=\"%(notes:X) %(notes:Y)\" may\nnot be something you can easily support.\n\n"},{"id":"423485","messageId":"CAOLTT8R2-uZQ4rAs+TNKSZXzfXjjB-=unuBUykMo=taguTPw7A@mail.gmail.com","threadId":"55585","inReplyTo":"xmqqsg34a5j8.fsf@gitster.g","subject":"Re: [PATCH] [GSOC] ref-filter: add %(notes) format atom","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2021-05-03T13:25:14Z","receivedAt":"2021-05-03T13:25:38Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Junio C Hamano <gitster@pobox.com> 于2021年5月3日周一 上午10:57写道：\n>\n> ZheNing Hu <adlternative@gmail.com> writes:\n>\n> > Note that `cat-file --batch` should be a superset of `ref-filter` and\n> > `--pretty`, because\n> > it supports all objects, while `ref-filter` only supports \"commit\" and\n> > \"tag\" two kinds\n> > of objects, and `--pretty` only supports \"commit\" one kind of object.\n>\n> What?  A ref can point at any kind of objects, not necessarily\n> commits and tags.  %(objectname), %(objecttype), etc. obviously\n> are applicable to any type of object.\n>\n\nThanks for correcting. I only saw tag and commit in the output\nof `git for-each-ref` before, and blob and tree are not processed\nin `grab_values` in `ref-filter.c`, which deepens my illusion.\n`git update-ref` can make a ref point to a blob object or tree object,\nalthough I don't know what these refs are used for... A reference to a\ncommit object makes sense, but if it is a blob, are there any suitable\nscenarios?\n\n> Another thing worth noting is that ref-filter needs to deal with\n> traits that are not tied to any particular object, but to the ref\n> itself, like who its upstream is and where it would be pushed to.\n>\n\nIndeed need to be considered \"%(push)\" \"%(remote)\" will change\n\"refname\".\n\n> > So it may be reasonable to provide `%(notes)` to \"commit\",\"tag\"\n> > objects in `cat-file --batch`\n> > in the future, now integrate them into ref-filter firstly.\n>\n> And you can attach notes to objects of any type, not limited to\n> commits and tags.\n>\n> >> >     So in this patch, I tried to migrate --pretty=%N to --format=%(notes).\n>\n> What do you mean by \"migrate\"?  Are you making both available?\n>\n\nWell, here are some incorrect statements, I just want to express that\nthe `--format=\"%(notes)\"` implemented in \"ref-filter\" has the same semantics\nas \"--pretty=%N\".\n\n> >> > diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\n> >> > index 2ae2478de706..07f037a16e13 100644\n> >> > --- a/Documentation/git-for-each-ref.txt\n> >> > +++ b/Documentation/git-for-each-ref.txt\n> >> > @@ -139,6 +139,9 @@ deltabase::\n> >> >       given object, if it is stored as a delta.  Otherwise it\n> >> >       expands to the null object name (all zeroes).\n> >> >\n> >> > +notes::\n> >> > +     The notes associated with the ref.\n>\n> \"The notes associated with the object pointed at by the ref\".\n>\n> A note is never associated with a ref.  It can only associated with\n> an object.\n>\n\nIndeed.\n\n> If we are going to have %(notes), it may be natural to desire\n> grabbing notes for the given object from specified notes ref, e.g.\n>\n>     git for-each-ref --format=\"%(notes:amlog) %(subject)\" zh/pretty-date-human\n>\n> may want to give the same kind of information as\n>\n>     git show -s --format='%N %s' --notes=amlog zh/pretty-date-human\n>\n> The underlying notes machinery however may not be prepared to work\n> with more than one notes tree at the same time, so\n>\n>     git for-each-ref --format=\"%(notes) %(subject)\" --notes=amlog zh/pretty-date-human\n>\n> might be a better syntax, as --format=\"%(notes:X) %(notes:Y)\" may\n> not be something you can easily support.\n>\n\nHere is a \"bad\" idea that might support this feature: use another subprocess\n\"git notes --refs=refs/notes/amlog\" :)\n\nThanks.\n--\nZheNing Hu\n"}]}