{"thread":{"id":"44247","subject":"[PATCH v4 2/7] ref-filter: add function to print single ref_array_item","startedAt":"2016-10-07T21:08:18Z","lastAt":"2016-10-19T17:07:43Z","messageCount":16,"participants":["santiago@nyu.edu","Santiago Torres","Jeff King"],"isPatch":true,"patchVersion":4,"patchTotal":7},"messages":[{"id":"303611","messageId":"20161007210721.20437-3-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 2/7] ref-filter: add function to print single ref_array_item","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:16Z","receivedAt":"2016-10-07T21:08:18Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Lukas Puehringer <luk.puehringer@gmail.com>\n\nref-filter functions are useful for printing git object information\nusing a format specifier. However, some other modules may not want to use\nthis functionality on a ref-array but only print a single item.\n\nExpose a pretty_print_ref function to create, pretty print and free\nindividual ref-items.\n\nSigned-off-by: Lukas Puehringer <luk.puehringer@gmail.com>\n---\n ref-filter.c | 10 ++++++++++\n ref-filter.h |  3 +++\n 2 files changed, 13 insertions(+)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 9adbb8a..cfbcd73 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -1637,6 +1637,16 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu\n \tputchar('\\n');\n }\n \n+void pretty_print_ref(const char *name, const unsigned char *sha1,\n+\t\tconst char *format, unsigned kind)\n+{\n+\tstruct ref_array_item *ref_item;\n+\tref_item = new_ref_array_item(name, sha1, 0);\n+\tref_item->kind = kind;\n+\tshow_ref_array_item(ref_item, format, 0);\n+\tfree_array_item(ref_item);\n+}\n+\n /*  If no sorting option is given, use refname to sort as default */\n struct ref_sorting *ref_default_sorting(void)\n {\ndiff --git a/ref-filter.h b/ref-filter.h\nindex 14d435e..3d23090 100644\n--- a/ref-filter.h\n+++ b/ref-filter.h\n@@ -107,4 +107,7 @@ struct ref_sorting *ref_default_sorting(void);\n /*  Function to parse --merged and --no-merged options */\n int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);\n \n+void pretty_print_ref(const char *name, const unsigned char *sha1,\n+\t\tconst char *format, unsigned kind);\n+\n #endif /*  REF_FILTER_H  */\n-- \n2.10.0\n\n"},{"id":"303612","messageId":"20161007210721.20437-1-santiago@nyu.edu","threadId":"44247","inReplyTo":null,"subject":"[PATCH v4 0/7] Add --format to tag verification","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:14Z","receivedAt":"2016-10-07T21:08:21Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Santiago Torres <santiago@nyu.edu>\n\nThis is the fourth iteration of the series in [1][2][3], which comes as a\nresult of the discussion in [4]. The main goal of this patch series is to bring\n--format to git tag verification so that upper-layer tools can inspect the\ncontent of a tag and make decisions based on those contents.\n\nIn this re-woll we:\n\n* Fixed the author fields and signed off by's throughout the patch\n  series\n\n* Added two more patches with unit tests to ensure the format specifier\n  behaves as expected\n\n* Fixed a missing initialization for the format specifier in verify-tag which\n  caused a crash.\n\n* Fixed an outdated git commit message that had the previous name of a\n  function definition.\n\nThanks,\n-Santiago\n\n[1] http://public-inbox.org/git/20160930221806.3398-1-santiago@nyu.edu/\n[2] http://public-inbox.org/git/20160922185317.349-1-santiago@nyu.edu/\n[3] http://public-inbox.org/git/20160926224233.32702-1-santiago@nyu.edu/\n[4] http://public-inbox.org/git/20160607195608.16643-1-santiago@nyu.edu/\n\n\nLukas Puehringer (4):\n  tag: add format specifier to gpg_verify_tag\n  gpg-interface, tag: add GPG_VERIFY_QUIET flag\n  ref-filter: add function to print single ref_array_item\n  builtin/tag: add --format argument for tag -v\n\nSantiago Torres (3):\n  builtin/verify-tag: add --format to verify-tag\n  t/t7030-verify-tag: Add --format specifier tests\n  t/t7004-tag: Add --format specifier tests\n\n Documentation/git-tag.txt        |  2 +-\n Documentation/git-verify-tag.txt |  2 +-\n builtin/tag.c                    | 34 +++++++++++++++++++++++-----------\n builtin/verify-tag.c             | 13 +++++++++++--\n gpg-interface.h                  |  1 +\n ref-filter.c                     | 10 ++++++++++\n ref-filter.h                     |  3 +++\n t/t7004-tag.sh                   | 16 ++++++++++++++++\n t/t7030-verify-tag.sh            | 16 ++++++++++++++++\n tag.c                            | 22 +++++++++++++++-------\n tag.h                            |  4 ++--\n 11 files changed, 99 insertions(+), 24 deletions(-)\n\n-- \n2.10.0\n\n"},{"id":"303613","messageId":"20161007210721.20437-5-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 4/7] builtin/verify-tag: add --format to verify-tag","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:18Z","receivedAt":"2016-10-07T21:08:28Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Santiago Torres <santiago@nyu.edu>\n\nCallers of verify-tag may want to cross-check the tagname from refs/tags\nwith the tagname from the tag object header upon GPG verification. This\nis to avoid tag refs that point to an incorrect object.\n\nAdd a --format parameter to git verify-tag to print the formatted tag\nobject header in addition to or instead of the --verbose or --raw GPG\nverification output.\n\nSigned-off-by: Santiago Torres <santiago@nyu.edu>\n---\n Documentation/git-verify-tag.txt |  2 +-\n builtin/verify-tag.c             | 13 +++++++++++--\n 2 files changed, 12 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt\nindex d590edc..0b8075d 100644\n--- a/Documentation/git-verify-tag.txt\n+++ b/Documentation/git-verify-tag.txt\n@@ -8,7 +8,7 @@ git-verify-tag - Check the GPG signature of tags\n SYNOPSIS\n --------\n [verse]\n-'git verify-tag' <tag>...\n+'git verify-tag' [--format=<format>] <tag>...\n \n DESCRIPTION\n -----------\ndiff --git a/builtin/verify-tag.c b/builtin/verify-tag.c\nindex de10198..745b6a6 100644\n--- a/builtin/verify-tag.c\n+++ b/builtin/verify-tag.c\n@@ -12,12 +12,14 @@\n #include <signal.h>\n #include \"parse-options.h\"\n #include \"gpg-interface.h\"\n+#include \"ref-filter.h\"\n \n static const char * const verify_tag_usage[] = {\n-\t\tN_(\"git verify-tag [-v | --verbose] <tag>...\"),\n+\t\tN_(\"git verify-tag [-v | --verbose] [--format=<format>] <tag>...\"),\n \t\tNULL\n };\n \n+\n static int git_verify_tag_config(const char *var, const char *value, void *cb)\n {\n \tint status = git_gpg_config(var, value, cb);\n@@ -30,9 +32,11 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)\n {\n \tint i = 1, verbose = 0, had_error = 0;\n \tunsigned flags = 0;\n+\tchar *fmt_pretty = NULL;\n \tconst struct option verify_tag_options[] = {\n \t\tOPT__VERBOSE(&verbose, N_(\"print tag contents\")),\n \t\tOPT_BIT(0, \"raw\", &flags, N_(\"print raw gpg status output\"), GPG_VERIFY_RAW),\n+\t\tOPT_STRING(  0 , \"format\", &fmt_pretty, N_(\"format\"), N_(\"format to use for the output\")),\n \t\tOPT_END()\n \t};\n \n@@ -46,12 +50,17 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)\n \tif (verbose)\n \t\tflags |= GPG_VERIFY_VERBOSE;\n \n+\tif (fmt_pretty) {\n+\t\tverify_ref_format(fmt_pretty);\n+\t\tflags |= GPG_VERIFY_QUIET;\n+\t}\n+\n \twhile (i < argc) {\n \t\tunsigned char sha1[20];\n \t\tconst char *name = argv[i++];\n \t\tif (get_sha1(name, sha1))\n \t\t\thad_error = !!error(\"tag '%s' not found.\", name);\n-\t\telse if (verify_and_format_tag(sha1, name, NULL, flags))\n+\t\telse if (verify_and_format_tag(sha1, name, fmt_pretty, flags))\n \t\t\thad_error = 1;\n \t}\n \treturn had_error;\n-- \n2.10.0\n\n"},{"id":"303614","messageId":"20161007210721.20437-4-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 3/7] tag: add format specifier to gpg_verify_tag","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:17Z","receivedAt":"2016-10-07T21:08:31Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Lukas Puehringer <luk.puehringer@gmail.com>\n\nCalling functions for gpg_verify_tag() may desire to print relevant\ninformation about the header for further verification. Add an optional\nformat argument to print any desired information after GPG verification.\n\nSigned-off-by: Lukas Puehringer <luk.puehringer@gmail.com>\n---\n builtin/tag.c        |  2 +-\n builtin/verify-tag.c |  2 +-\n tag.c                | 17 +++++++++++------\n tag.h                |  4 ++--\n 4 files changed, 15 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 50e4ae5..14f3b48 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -105,7 +105,7 @@ static int delete_tag(const char *name, const char *ref,\n static int verify_tag(const char *name, const char *ref,\n \t\t\t\tconst unsigned char *sha1)\n {\n-\treturn gpg_verify_tag(sha1, name, GPG_VERIFY_VERBOSE);\n+\treturn verify_and_format_tag(sha1, name, NULL, GPG_VERIFY_VERBOSE);\n }\n \n static int do_sign(struct strbuf *buffer)\ndiff --git a/builtin/verify-tag.c b/builtin/verify-tag.c\nindex 99f8148..de10198 100644\n--- a/builtin/verify-tag.c\n+++ b/builtin/verify-tag.c\n@@ -51,7 +51,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)\n \t\tconst char *name = argv[i++];\n \t\tif (get_sha1(name, sha1))\n \t\t\thad_error = !!error(\"tag '%s' not found.\", name);\n-\t\telse if (gpg_verify_tag(sha1, name, flags))\n+\t\telse if (verify_and_format_tag(sha1, name, NULL, flags))\n \t\t\thad_error = 1;\n \t}\n \treturn had_error;\ndiff --git a/tag.c b/tag.c\nindex 291073f..d3512c0 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -4,6 +4,7 @@\n #include \"tree.h\"\n #include \"blob.h\"\n #include \"gpg-interface.h\"\n+#include \"ref-filter.h\"\n \n const char *tag_type = \"tag\";\n \n@@ -33,8 +34,8 @@ static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags)\n \treturn ret;\n }\n \n-int gpg_verify_tag(const unsigned char *sha1, const char *name_to_report,\n-\t\tunsigned flags)\n+int verify_and_format_tag(const unsigned char *sha1, const char *name,\n+\t\tconst char *fmt_pretty, unsigned flags)\n {\n \tenum object_type type;\n \tchar *buf;\n@@ -44,21 +45,25 @@ int gpg_verify_tag(const unsigned char *sha1, const char *name_to_report,\n \ttype = sha1_object_info(sha1, NULL);\n \tif (type != OBJ_TAG)\n \t\treturn error(\"%s: cannot verify a non-tag object of type %s.\",\n-\t\t\t\tname_to_report ?\n-\t\t\t\tname_to_report :\n+\t\t\t\tname ?\n+\t\t\t\tname :\n \t\t\t\tfind_unique_abbrev(sha1, DEFAULT_ABBREV),\n \t\t\t\ttypename(type));\n \n \tbuf = read_sha1_file(sha1, &type, &size);\n \tif (!buf)\n \t\treturn error(\"%s: unable to read file.\",\n-\t\t\t\tname_to_report ?\n-\t\t\t\tname_to_report :\n+\t\t\t\tname ?\n+\t\t\t\tname :\n \t\t\t\tfind_unique_abbrev(sha1, DEFAULT_ABBREV));\n \n \tret = run_gpg_verify(buf, size, flags);\n \n \tfree(buf);\n+\n+\tif (fmt_pretty)\n+\t\tpretty_print_ref(name, sha1, fmt_pretty, FILTER_REFS_TAGS);\n+\n \treturn ret;\n }\n \ndiff --git a/tag.h b/tag.h\nindex a5721b6..896b9c2 100644\n--- a/tag.h\n+++ b/tag.h\n@@ -17,7 +17,7 @@ extern int parse_tag_buffer(struct tag *item, const void *data, unsigned long si\n extern int parse_tag(struct tag *item);\n extern struct object *deref_tag(struct object *, const char *, int);\n extern struct object *deref_tag_noverify(struct object *);\n-extern int gpg_verify_tag(const unsigned char *sha1,\n-\t\tconst char *name_to_report, unsigned flags);\n+extern int verify_and_format_tag(const unsigned char *sha1, const char *name,\n+\t\tconst char *fmt_pretty, unsigned flags);\n \n #endif /* TAG_H */\n-- \n2.10.0\n\n"},{"id":"303615","messageId":"20161007210721.20437-2-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 1/7] gpg-interface, tag: add GPG_VERIFY_QUIET flag","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:15Z","receivedAt":"2016-10-07T21:08:32Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Lukas Puehringer <luk.puehringer@gmail.com>\n\nFunctions that print git object information may require that the\ngpg-interface functions be silent. Add GPG_VERIFY_QUIET flag and prevent\nprint_signature_buffer from being called if flag is set.\n\nSigned-off-by: Lukas Puehringer <luk.puehringer@gmail.com>\n---\n gpg-interface.h | 1 +\n tag.c           | 5 ++++-\n 2 files changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/gpg-interface.h b/gpg-interface.h\nindex ea68885..85dc982 100644\n--- a/gpg-interface.h\n+++ b/gpg-interface.h\n@@ -3,6 +3,7 @@\n \n #define GPG_VERIFY_VERBOSE\t1\n #define GPG_VERIFY_RAW\t\t2\n+#define GPG_VERIFY_QUIET\t4\n \n struct signature_check {\n \tchar *payload;\ndiff --git a/tag.c b/tag.c\nindex d1dcd18..291073f 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -3,6 +3,7 @@\n #include \"commit.h\"\n #include \"tree.h\"\n #include \"blob.h\"\n+#include \"gpg-interface.h\"\n \n const char *tag_type = \"tag\";\n \n@@ -24,7 +25,9 @@ static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags)\n \n \tret = check_signature(buf, payload_size, buf + payload_size,\n \t\t\t\tsize - payload_size, &sigc);\n-\tprint_signature_buffer(&sigc, flags);\n+\n+\tif (!(flags & GPG_VERIFY_QUIET))\n+\t\tprint_signature_buffer(&sigc, flags);\n \n \tsignature_check_clear(&sigc);\n \treturn ret;\n-- \n2.10.0\n\n"},{"id":"303616","messageId":"20161007210721.20437-6-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 5/7] builtin/tag: add --format argument for tag -v","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:19Z","receivedAt":"2016-10-07T21:08:35Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Lukas Puehringer <luk.puehringer@gmail.com>\n\nAdding --format to git tag -v mutes the default output of the GPG\nverification and instead prints the formatted tag object.\nThis allows callers to cross-check the tagname from refs/tags with\nthe tagname from the tag object header upon GPG verification.\n\nThe callback function for for_each_tag_name() didn't allow callers to\npass custom data to their callback functions. Add a new opaque pointer\nto each_tag_name_fn's parameter to allow this.\n\nSigned-off-by: Lukas Puehringer <luk.puehringer@gmail.com>\n---\n Documentation/git-tag.txt |  2 +-\n builtin/tag.c             | 34 +++++++++++++++++++++++-----------\n builtin/verify-tag.c      |  2 +-\n 3 files changed, 25 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt\nindex 7ecca8e..3bb5e3c 100644\n--- a/Documentation/git-tag.txt\n+++ b/Documentation/git-tag.txt\n@@ -15,7 +15,7 @@ SYNOPSIS\n 'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]\n \t[--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>]\n \t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]\n-'git tag' -v <tagname>...\n+'git tag' -v [--format=<format>] <tagname>...\n \n DESCRIPTION\n -----------\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 14f3b48..7730fd0 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -24,7 +24,7 @@ static const char * const git_tag_usage[] = {\n \tN_(\"git tag -d <tagname>...\"),\n \tN_(\"git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]\"\n \t\t\"\\n\\t\\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]\"),\n-\tN_(\"git tag -v <tagname>...\"),\n+\tN_(\"git tag -v [--format=<format>] <tagname>...\"),\n \tNULL\n };\n \n@@ -66,15 +66,17 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con\n }\n \n typedef int (*each_tag_name_fn)(const char *name, const char *ref,\n-\t\t\t\tconst unsigned char *sha1);\n+\t\t\t\tconst unsigned char *sha1, void *cb_data);\n \n-static int for_each_tag_name(const char **argv, each_tag_name_fn fn)\n+static int for_each_tag_name(const char **argv, each_tag_name_fn fn,\n+\t\tvoid *cb_data)\n {\n \tconst char **p;\n \tchar ref[PATH_MAX];\n \tint had_error = 0;\n \tunsigned char sha1[20];\n \n+\n \tfor (p = argv; *p; p++) {\n \t\tif (snprintf(ref, sizeof(ref), \"refs/tags/%s\", *p)\n \t\t\t\t\t>= sizeof(ref)) {\n@@ -87,14 +89,14 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)\n \t\t\thad_error = 1;\n \t\t\tcontinue;\n \t\t}\n-\t\tif (fn(*p, ref, sha1))\n+\t\tif (fn(*p, ref, sha1, cb_data))\n \t\t\thad_error = 1;\n \t}\n \treturn had_error;\n }\n \n static int delete_tag(const char *name, const char *ref,\n-\t\t\t\tconst unsigned char *sha1)\n+\t\t\t\tconst unsigned char *sha1, void *cb_data)\n {\n \tif (delete_ref(ref, sha1, 0))\n \t\treturn 1;\n@@ -103,9 +105,16 @@ static int delete_tag(const char *name, const char *ref,\n }\n \n static int verify_tag(const char *name, const char *ref,\n-\t\t\t\tconst unsigned char *sha1)\n+\t\t\t\tconst unsigned char *sha1, void *cb_data)\n {\n-\treturn verify_and_format_tag(sha1, name, NULL, GPG_VERIFY_VERBOSE);\n+\tint flags;\n+\tchar *fmt_pretty = cb_data;\n+\tflags = GPG_VERIFY_VERBOSE;\n+\n+\tif (fmt_pretty)\n+\t\tflags = GPG_VERIFY_QUIET;\n+\n+\treturn verify_and_format_tag(sha1, name, fmt_pretty, flags);\n }\n \n static int do_sign(struct strbuf *buffer)\n@@ -334,7 +343,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tstruct strbuf err = STRBUF_INIT;\n \tstruct ref_filter filter;\n \tstatic struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;\n-\tconst char *format = NULL;\n+\tchar *format = NULL;\n \tstruct option options[] = {\n \t\tOPT_CMDMODE('l', \"list\", &cmdmode, N_(\"list tag names\"), 'l'),\n \t\t{ OPTION_INTEGER, 'n', NULL, &filter.lines, N_(\"n\"),\n@@ -424,9 +433,12 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tif (filter.merge_commit)\n \t\tdie(_(\"--merged and --no-merged option are only allowed with -l\"));\n \tif (cmdmode == 'd')\n-\t\treturn for_each_tag_name(argv, delete_tag);\n-\tif (cmdmode == 'v')\n-\t\treturn for_each_tag_name(argv, verify_tag);\n+\t\treturn for_each_tag_name(argv, delete_tag, NULL);\n+\tif (cmdmode == 'v') {\n+\t\tif (format)\n+\t\t\tverify_ref_format(format);\n+\t\treturn for_each_tag_name(argv, verify_tag, format);\n+\t}\n \n \tif (msg.given || msgfile) {\n \t\tif (msg.given && msgfile)\n-- \n2.10.0\n\n"},{"id":"303617","messageId":"20161007210721.20437-7-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 6/7] t/t7030-verify-tag: Add --format specifier tests","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:20Z","receivedAt":"2016-10-07T21:08:36Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Santiago Torres <santiago@nyu.edu>\n\nVerify-tag now provides --format specifiers to inspect and ensure the\ncontents of the tag are proper. We add two tests to ensure this\nfunctionality works as expected: the return value should indicate if\nverification passed, and the format specifiers must be respected.\n\nSigned-off-by: Santiago Torres <santiago@nyu.edu>\n---\n t/t7030-verify-tag.sh | 16 ++++++++++++++++\n 1 file changed, 16 insertions(+)\n\ndiff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh\nindex 07079a4..ce37fd9 100755\n--- a/t/t7030-verify-tag.sh\n+++ b/t/t7030-verify-tag.sh\n@@ -125,4 +125,20 @@ test_expect_success GPG 'verify multiple tags' '\n \ttest_cmp expect.stderr actual.stderr\n '\n \n+test_expect_success 'verifying tag with --format' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : fourth-signed\n+\tEOF\n+\tgit verify-tag --format=\"tagname : %(tag)\" \"fourth-signed\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'verifying a forged tag with --format fail and format accordingly' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : 7th forged-signed\n+\tEOF\n+\ttest_must_fail git verify-tag --format=\"tagname : %(tag)\" $(cat forged1.tag) >actual-forged &&\n+\ttest_cmp expect actual-forged\n+'\n+\n test_done\n-- \n2.10.0\n\n"},{"id":"303618","messageId":"20161007210721.20437-8-santiago@nyu.edu","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"[PATCH v4 7/7] t/t7004-tag: Add --format specifier tests","fromName":"","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-07T21:07:21Z","receivedAt":"2016-10-07T21:08:37Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"From: Santiago Torres <santiago@nyu.edu>\n\ntag -v now supports --format specifiers to inspect the contents of a tag\nupon verification. Add two tests to ensure this behavior is respected in\nfuture changes.\n\nSigned-off-by: Santiago Torres <santiago@nyu.edu>\n---\n t/t7004-tag.sh | 16 ++++++++++++++++\n 1 file changed, 16 insertions(+)\n\ndiff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\nindex 8b0f71a..633b089 100755\n--- a/t/t7004-tag.sh\n+++ b/t/t7004-tag.sh\n@@ -847,6 +847,22 @@ test_expect_success GPG 'verifying a forged tag should fail' '\n \ttest_must_fail git tag -v forged-tag\n '\n \n+test_expect_success 'verifying a proper tag with --format pass and format accordingly' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : signed-tag\n+\tEOF\n+\tgit tag -v --format=\"tagname : %(tag)\" \"signed-tag\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'verifying a forged tag with --format fail and format accordingly' '\n+\tcat >expect <<-\\EOF &&\n+\ttagname : forged-tag\n+\tEOF\n+\ttest_must_fail git tag -v --format=\"tagname : %(tag)\" \"forged-tag\" >actual &&\n+\ttest_cmp expect actual\n+'\n+\n # blank and empty messages for signed tags:\n \n get_tag_header empty-signed-tag $commit commit $time >expect\n-- \n2.10.0\n\n"},{"id":"303894","messageId":"20161011174349.dp44e4ir6tweuzzv@LykOS.localdomain","threadId":"44247","inReplyTo":"20161007210721.20437-1-santiago@nyu.edu","subject":"Re: [PATCH v4 0/7] Add --format to tag verification","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-11T17:43:49Z","receivedAt":"2016-10-11T17:55:53Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"Hi,\n\nI noticed there were no replies for this thread. I was curious if it got\nburied because I sent it on the Friday evening before a long weekend.\n\nI don't mean to pressure or anything.\n\nThanks!\n-Santiago.\n\n\nOn Fri, Oct 07, 2016 at 05:07:14PM -0400, santiago@nyu.edu wrote:\n> From: Santiago Torres <santiago@nyu.edu>\n> \n> This is the fourth iteration of the series in [1][2][3], which comes as a\n> result of the discussion in [4]. The main goal of this patch series is to bring\n> --format to git tag verification so that upper-layer tools can inspect the\n> content of a tag and make decisions based on those contents.\n> \n> In this re-woll we:\n> \n> * Fixed the author fields and signed off by's throughout the patch\n>   series\n> \n> * Added two more patches with unit tests to ensure the format specifier\n>   behaves as expected\n> \n> * Fixed a missing initialization for the format specifier in verify-tag which\n>   caused a crash.\n> \n> * Fixed an outdated git commit message that had the previous name of a\n>   function definition.\n> \n> Thanks,\n> -Santiago\n> \n> [1] http://public-inbox.org/git/20160930221806.3398-1-santiago@nyu.edu/\n> [2] http://public-inbox.org/git/20160922185317.349-1-santiago@nyu.edu/\n> [3] http://public-inbox.org/git/20160926224233.32702-1-santiago@nyu.edu/\n> [4] http://public-inbox.org/git/20160607195608.16643-1-santiago@nyu.edu/\n> \n> \n> Lukas Puehringer (4):\n>   tag: add format specifier to gpg_verify_tag\n>   gpg-interface, tag: add GPG_VERIFY_QUIET flag\n>   ref-filter: add function to print single ref_array_item\n>   builtin/tag: add --format argument for tag -v\n> \n> Santiago Torres (3):\n>   builtin/verify-tag: add --format to verify-tag\n>   t/t7030-verify-tag: Add --format specifier tests\n>   t/t7004-tag: Add --format specifier tests\n> \n>  Documentation/git-tag.txt        |  2 +-\n>  Documentation/git-verify-tag.txt |  2 +-\n>  builtin/tag.c                    | 34 +++++++++++++++++++++++-----------\n>  builtin/verify-tag.c             | 13 +++++++++++--\n>  gpg-interface.h                  |  1 +\n>  ref-filter.c                     | 10 ++++++++++\n>  ref-filter.h                     |  3 +++\n>  t/t7004-tag.sh                   | 16 ++++++++++++++++\n>  t/t7030-verify-tag.sh            | 16 ++++++++++++++++\n>  tag.c                            | 22 +++++++++++++++-------\n>  tag.h                            |  4 ++--\n>  11 files changed, 99 insertions(+), 24 deletions(-)\n> \n> -- \n> 2.10.0\n> \n"},{"id":"304383","messageId":"20161019090432.xip4r7f6xwcciqk4@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161007210721.20437-5-santiago@nyu.edu","subject":"Re: [PATCH v4 4/7] builtin/verify-tag: add --format to verify-tag","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T09:04:33Z","receivedAt":"2016-10-19T09:06:56Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 07, 2016 at 05:07:18PM -0400, santiago@nyu.edu wrote:\n\n> @@ -46,12 +50,17 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)\n>  \tif (verbose)\n>  \t\tflags |= GPG_VERIFY_VERBOSE;\n>  \n> +\tif (fmt_pretty) {\n> +\t\tverify_ref_format(fmt_pretty);\n> +\t\tflags |= GPG_VERIFY_QUIET;\n> +\t}\n\nI see why you would want to disable the normal output when there is a\ncustom format. But it seems a shame that the GPG information cannot be\nretrieved as part of that format.\n\nI think in the long run we'd want something like pretty.c's \"%G\"\nplaceholders for the ref-filter pretty-printer. But I think we are OK to\ndo this patch without it. It allows at least:\n\n  tag=v2.0.0\n  got=$(git verify-tag --format='%(tag)' \"$tag\") &&\n  test \"$tag\" = \"$got\" ||\n  echo >&2 \"verification failed\"\n\nwhich is better than what we have now, and can be extended in the\nfuture.\n\n-Peff\n"},{"id":"304392","messageId":"20161019091323.jrirwruwex7l7yj2@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161007210721.20437-7-santiago@nyu.edu","subject":"Re: [PATCH v4 6/7] t/t7030-verify-tag: Add --format specifier tests","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T09:13:23Z","receivedAt":"2016-10-19T15:38:47Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 07, 2016 at 05:07:20PM -0400, santiago@nyu.edu wrote:\n\n> Verify-tag now provides --format specifiers to inspect and ensure the\n> contents of the tag are proper. We add two tests to ensure this\n> functionality works as expected: the return value should indicate if\n> verification passed, and the format specifiers must be respected.\n\nSounds good.\n\n> +test_expect_success 'verifying tag with --format' '\n> +\tcat >expect <<-\\EOF &&\n> +\ttagname : fourth-signed\n> +\tEOF\n> +\tgit verify-tag --format=\"tagname : %(tag)\" \"fourth-signed\" >actual &&\n> +\ttest_cmp expect actual\n> +'\n\nI suppose it's a matter of style, but for a single-line expectation I\nwould just do:\n\n  echo \"tagname : fourth-signed\" >expect &&\n\nwhich is shorter and saves a process invocation.\n\nDitto on the next patch (which IMHO could just be squashed into a single\npatch).\n\n-Peff\n"},{"id":"304394","messageId":"20161019091044.k3ewbfxjj6ihv5o5@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161007210721.20437-6-santiago@nyu.edu","subject":"Re: [PATCH v4 5/7] builtin/tag: add --format argument for tag -v","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T09:10:44Z","receivedAt":"2016-10-19T15:41:09Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 07, 2016 at 05:07:19PM -0400, santiago@nyu.edu wrote:\n\n> Adding --format to git tag -v mutes the default output of the GPG\n> verification and instead prints the formatted tag object.\n\nThe same comments apply to \"mutes\" here, as to the previous patch (which\nis to say I think we may want something more, but this is probably OK\nfor now).\n\n> diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt\n> index 7ecca8e..3bb5e3c 100644\n> --- a/Documentation/git-tag.txt\n> +++ b/Documentation/git-tag.txt\n> @@ -15,7 +15,7 @@ SYNOPSIS\n>  'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]\n>  \t[--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>]\n>  \t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]\n> -'git tag' -v <tagname>...\n> +'git tag' -v [--format=<format>] <tagname>...\n\nJust thinking out loud, but if we had ref-filter placeholders that\ntriggered GPG verification, you could do this all with the listing mode,\nlike:\n\n  git tag --format='%(gpgstatus) %(tag) %(refname:short)'\n\nand verify multiple tags (or give a single tag to limit it to just one).\n\nI don't think that's any kind of blocker for this series. We already\nhave \"-v\", and adding --format to it is reasonable, even if we\neventually move to a world where people can use the listing mode. Like I\nsaid, just thinking out loud.\n\n> +static int for_each_tag_name(const char **argv, each_tag_name_fn fn,\n> +\t\tvoid *cb_data)\n>  {\n>  \tconst char **p;\n>  \tchar ref[PATH_MAX];\n>  \tint had_error = 0;\n>  \tunsigned char sha1[20];\n>  \n> +\n>  \tfor (p = argv; *p; p++) {\n\nExtra space?\n\n>  static int verify_tag(const char *name, const char *ref,\n> -\t\t\t\tconst unsigned char *sha1)\n> +\t\t\t\tconst unsigned char *sha1, void *cb_data)\n>  {\n> -\treturn verify_and_format_tag(sha1, name, NULL, GPG_VERIFY_VERBOSE);\n> +\tint flags;\n\nProbably doesn't matter much, but these flags are defined as \"unsigned\"\nelsewhere.\n\n-Peff\n"},{"id":"304395","messageId":"20161019091641.vcv3snlg5xr3yazs@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161019085543.om7v7eowfaushags@sigill.intra.peff.net","subject":"Re: [PATCH v4 2/7] ref-filter: add function to print single ref_array_item","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T09:16:42Z","receivedAt":"2016-10-19T15:41:54Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 19, 2016 at 04:55:43AM -0400, Jeff King wrote:\n\n> > diff --git a/ref-filter.h b/ref-filter.h\n> > index 14d435e..3d23090 100644\n> > --- a/ref-filter.h\n> > +++ b/ref-filter.h\n> > @@ -107,4 +107,7 @@ struct ref_sorting *ref_default_sorting(void);\n> >  /*  Function to parse --merged and --no-merged options */\n> >  int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);\n> >  \n> > +void pretty_print_ref(const char *name, const unsigned char *sha1,\n> > +\t\tconst char *format, unsigned kind);\n> > +\n> \n> What are the possible values for \"kind\"? I guess these should come from\n> FILTER_REFS_TAGS, BRANCHES, etc. It's probably worth documenting that.\n> Alternatively, is it possible to just determine this from the name? It\n> looks like filter_ref_kind() is how it happens for a normal ref-filter.\n\nI guess that may complicate things for the caller you add in this\nseries, which may not have a fully-qualified refname (which is obviously\nhow filter_ref_kind() figures it out). I'd argue that is a bug, though,\nas things like \"%(refname)\" are generally expected to print out the\nfully refname (\"git tag --format=%(refname)\" does so, and you can use\n\"%(refname:short)\" if you want the shorter part).\n\n-Peff\n"},{"id":"304396","messageId":"20161019085543.om7v7eowfaushags@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161007210721.20437-3-santiago@nyu.edu","subject":"Re: [PATCH v4 2/7] ref-filter: add function to print single ref_array_item","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T08:55:43Z","receivedAt":"2016-10-19T15:46:41Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 07, 2016 at 05:07:16PM -0400, santiago@nyu.edu wrote:\n\n> From: Lukas Puehringer <luk.puehringer@gmail.com>\n> \n> ref-filter functions are useful for printing git object information\n> using a format specifier. However, some other modules may not want to use\n> this functionality on a ref-array but only print a single item.\n> \n> Expose a pretty_print_ref function to create, pretty print and free\n> individual ref-items.\n\nMakes sense.\n\n> diff --git a/ref-filter.h b/ref-filter.h\n> index 14d435e..3d23090 100644\n> --- a/ref-filter.h\n> +++ b/ref-filter.h\n> @@ -107,4 +107,7 @@ struct ref_sorting *ref_default_sorting(void);\n>  /*  Function to parse --merged and --no-merged options */\n>  int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);\n>  \n> +void pretty_print_ref(const char *name, const unsigned char *sha1,\n> +\t\tconst char *format, unsigned kind);\n> +\n\nWhat are the possible values for \"kind\"? I guess these should come from\nFILTER_REFS_TAGS, BRANCHES, etc. It's probably worth documenting that.\nAlternatively, is it possible to just determine this from the name? It\nlooks like filter_ref_kind() is how it happens for a normal ref-filter.\n\n-Peff\n"},{"id":"304398","messageId":"20161019085115.thvsf5muhyvmvgj2@sigill.intra.peff.net","threadId":"44247","inReplyTo":"20161007210721.20437-2-santiago@nyu.edu","subject":"Re: [PATCH v4 1/7] gpg-interface, tag: add GPG_VERIFY_QUIET flag","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-10-19T08:51:15Z","receivedAt":"2016-10-19T15:47:27Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 07, 2016 at 05:07:15PM -0400, santiago@nyu.edu wrote:\n\n> From: Lukas Puehringer <luk.puehringer@gmail.com>\n> \n> Functions that print git object information may require that the\n> gpg-interface functions be silent. Add GPG_VERIFY_QUIET flag and prevent\n> print_signature_buffer from being called if flag is set.\n\nThe layering here is a little funny. The gpg-interface code allocates a\nnew flag, but none of its functions do anything with it.  Instead, it's\nacted on only by the run_gpg_verify() command local to tag.c.\n\nI guess this \"flags\" variable comes to us from other callsites via\ngpg_verify_tag. That's still in tag.c, but it's arguably part of the gpg\ninterface.\n\nSo I think it's OK.\n\n-Peff\n"},{"id":"304402","messageId":"20161019170733.ey3d53miykn5t5cq@LykOS.localdomain","threadId":"44247","inReplyTo":"20161019091641.vcv3snlg5xr3yazs@sigill.intra.peff.net","subject":"Re: [PATCH v4 2/7] ref-filter: add function to print single ref_array_item","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-10-19T17:07:34Z","receivedAt":"2016-10-19T17:07:43Z","isPatch":true,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"On Wed, Oct 19, 2016 at 05:16:42AM -0400, Jeff King wrote:\n> On Wed, Oct 19, 2016 at 04:55:43AM -0400, Jeff King wrote:\n> \n> > > diff --git a/ref-filter.h b/ref-filter.h\n> > > index 14d435e..3d23090 100644\n> > > --- a/ref-filter.h\n> > > +++ b/ref-filter.h\n> > > @@ -107,4 +107,7 @@ struct ref_sorting *ref_default_sorting(void);\n> > >  /*  Function to parse --merged and --no-merged options */\n> > >  int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);\n> > >  \n> > > +void pretty_print_ref(const char *name, const unsigned char *sha1,\n> > > +\t\tconst char *format, unsigned kind);\n> > > +\n> > \n> > What are the possible values for \"kind\"? I guess these should come from\n> > FILTER_REFS_TAGS, BRANCHES, etc. It's probably worth documenting that.\n> > Alternatively, is it possible to just determine this from the name? It\n> > looks like filter_ref_kind() is how it happens for a normal ref-filter.\n> \n> I guess that may complicate things for the caller you add in this\n> series, which may not have a fully-qualified refname (which is obviously\n> how filter_ref_kind() figures it out). I'd argue that is a bug, though,\n> as things like \"%(refname)\" are generally expected to print out the\n> fully refname (\"git tag --format=%(refname)\" does so, and you can use\n> \"%(refname:short)\" if you want the shorter part).\n\nHmm, I hadn't actually noticed that. Do you have any suggestions in how to\naddress this?\n\nIn general this feels like a consequence of disambiguating .git/tags/*\nwithin builtin/tag.c rather than letting ref-filter figure it out.\n\nThanks,\n-Santiago.\n"}]}