builtin/tag: add --format argument for tag -v

Adding --format to git tag -v mutes the default output of the GPG
verification and instead prints the formatted tag object.
This allows callers to cross-check the tagname from refs/tags with
the tagname from the tag object header upon GPG verification.

The callback function for for_each_tag_name() didn't allow callers to
pass custom data to their callback functions. Add a new opaque pointer
to each_tag_name_fn's parameter to allow this.

Signed-off-by: Lukas Puehringer <luk.puehringer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Lukas Puehringer 2017-01-17 18:37:21 -05:00 committed by Junio C Hamano
parent ff3c8c8f12
commit 07d347cf9a
2 changed files with 28 additions and 11 deletions

View file

@ -15,7 +15,7 @@ SYNOPSIS
'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
[--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>]
[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]
'git tag' -v <tagname>...
'git tag' -v [--format=<format>] <tagname>...
DESCRIPTION
-----------

View file

@ -24,7 +24,7 @@ static const char * const git_tag_usage[] = {
N_("git tag -d <tagname>..."),
N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]"
"\n\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"),
N_("git tag -v <tagname>..."),
N_("git tag -v [--format=<format>] <tagname>..."),
NULL
};
@ -66,9 +66,10 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
}
typedef int (*each_tag_name_fn)(const char *name, const char *ref,
const unsigned char *sha1);
const unsigned char *sha1, const void *cb_data);
static int for_each_tag_name(const char **argv, each_tag_name_fn fn)
static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
const void *cb_data)
{
const char **p;
char ref[PATH_MAX];
@ -87,14 +88,14 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)
had_error = 1;
continue;
}
if (fn(*p, ref, sha1))
if (fn(*p, ref, sha1, cb_data))
had_error = 1;
}
return had_error;
}
static int delete_tag(const char *name, const char *ref,
const unsigned char *sha1)
const unsigned char *sha1, const void *cb_data)
{
if (delete_ref(ref, sha1, 0))
return 1;
@ -103,9 +104,22 @@ static int delete_tag(const char *name, const char *ref,
}
static int verify_tag(const char *name, const char *ref,
const unsigned char *sha1)
const unsigned char *sha1, const void *cb_data)
{
return gpg_verify_tag(sha1, name, GPG_VERIFY_VERBOSE);
int flags;
const char *fmt_pretty = cb_data;
flags = GPG_VERIFY_VERBOSE;
if (fmt_pretty)
flags = GPG_VERIFY_OMIT_STATUS;
if (gpg_verify_tag(sha1, name, flags))
return -1;
if (fmt_pretty)
pretty_print_ref(name, sha1, fmt_pretty);
return 0;
}
static int do_sign(struct strbuf *buffer)
@ -424,9 +438,12 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (filter.merge_commit)
die(_("--merged and --no-merged option are only allowed with -l"));
if (cmdmode == 'd')
return for_each_tag_name(argv, delete_tag);
if (cmdmode == 'v')
return for_each_tag_name(argv, verify_tag);
return for_each_tag_name(argv, delete_tag, NULL);
if (cmdmode == 'v') {
if (format)
verify_ref_format(format);
return for_each_tag_name(argv, verify_tag, format);
}
if (msg.given || msgfile) {
if (msg.given && msgfile)