All of lore.kernel.org
 help / color / mirror / Atom feed
From: "ZheNing Hu via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	ZheNing Hu <adlternative@gmail.com>,
	ZheNing Hu <adlternative@gmail.com>
Subject: [PATCH 4/4] ref-filter: let tag verify use %(refname:lstrip=2) by default
Date: Mon, 20 Sep 2021 07:37:56 +0000	[thread overview]
Message-ID: <d4e77765a8f5478c360fe78e72eb556ecdc326a5.1632123476.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1042.git.1632123476.gitgitgadget@gmail.com>

From: ZheNing Hu <adlternative@gmail.com>

Because git verify-tag or git tag --verify are using command line
parameters we pass as the %(refname) output (e.g. `git verify-tag
--format="verify: %(refname)" c06b72d02` will output
"verify: c06b72d02"). This is an design error, but it is widely
used by some scripts.

After we fix the bug that git verify_tag and git tag --verify
cannot use %(symref) correctly, we still need to make %(refname)
keep the same output as in the past. So add special_tag_verify to
ref_array_item and ref_format, when this flag is setted and we
are using refname atom default output formats such as %(refname),
%(symref), modify the attribute of the atom corresponding to
%(refname) in get_refname() and get_symref() and
fill_remote_ref_details(), which let show_ref() output something
like %(refname:lstrip=2). After show_ref() completes, restore the
atom attribute as their origin state.

We can set special_tag_verify flag directly in tag.c, but in
verify_tag.c, if we didn't get a refname from repo_dwim_ref(), we
don’t need to set special_tag_verify of ref_format and change its
output form, otherwise, set it.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 builtin/tag.c         |  1 +
 builtin/verify-tag.c  |  5 ++++-
 ref-filter.c          | 44 +++++++++++++++++++++++++++++++++----------
 ref-filter.h          |  2 ++
 t/t7030-verify-tag.sh | 23 ++++++++++++++++++++++
 5 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/builtin/tag.c b/builtin/tag.c
index ce5678d179f..bf2acb9f832 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -149,6 +149,7 @@ static int verify_tag(const char *name, const char *ref,
 	int flags;
 	struct ref_format *format = cb_data;
 	flags = GPG_VERIFY_VERBOSE;
+	format->special_tag_verify = 1;
 
 	if (format->format)
 		flags = GPG_VERIFY_OMIT_STATUS;
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index efc8282782a..dd2ff94eac9 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -61,6 +61,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
 		const char *name = argv[i++];
 		char *refname;
 		int ref_flags;
+		format.special_tag_verify = 0;
 
 		if (get_oid(name, &oid)) {
 			had_error = !!error("tag '%s' not found.", name);
@@ -72,8 +73,10 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
 			continue;
 		}
 
-		if (repo_dwim_ref(the_repository, name, strlen(name), &oid, &refname, 0, &ref_flags, 1))
+		if (repo_dwim_ref(the_repository, name, strlen(name), &oid, &refname, 0, &ref_flags, 1)) {
 			name = refname;
+			format.special_tag_verify = 1;
+		}
 		if (format.format)
 			pretty_print_ref(name, &oid, &format, ref_flags);
 	}
diff --git a/ref-filter.c b/ref-filter.c
index 6c51ef25136..c7c3182ab5b 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1640,12 +1640,19 @@ static const char *show_ref(struct refname_atom *atom, const char *refname)
 }
 
 static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
-				    struct branch *branch, const char **s)
+				    struct branch *branch, const char **s, struct ref_array_item *ref)
 {
 	int num_ours, num_theirs;
-	if (atom->u.remote_ref.option == RR_REF)
-		*s = show_ref(&atom->u.remote_ref.refname, refname);
-	else if (atom->u.remote_ref.option == RR_TRACK) {
+	if (atom->u.remote_ref.option == RR_REF) {
+		if (ref->special_tag_verify && atom->u.remote_ref.refname.option == R_NORMAL) {
+			atom->u.remote_ref.refname.option = R_LSTRIP;
+			atom->u.remote_ref.refname.lstrip = 2;
+			*s = show_ref(&atom->u.remote_ref.refname, refname);
+			atom->u.remote_ref.refname.option = R_NORMAL;
+		} else {
+			*s = show_ref(&atom->u.remote_ref.refname, refname);
+		}
+	} else if (atom->u.remote_ref.option == RR_TRACK) {
 		if (stat_tracking_info(branch, &num_ours, &num_theirs,
 				       NULL, atom->u.remote_ref.push,
 				       AHEAD_BEHIND_FULL) < 0) {
@@ -1726,17 +1733,33 @@ char *get_head_description(void)
 
 static const char *get_symref(struct used_atom *atom, struct ref_array_item *ref)
 {
-	if (!ref->symref)
+	if (!ref->symref) {
 		return xstrdup("");
-	else
+	} else if (ref->special_tag_verify && atom->u.refname.option == R_NORMAL) {
+		atom->u.refname.option = R_LSTRIP;
+		atom->u.refname.lstrip = 2;
+		return show_ref(&atom->u.refname, ref->symref);
+		atom->u.refname.option = R_NORMAL;
+	} else {
 		return show_ref(&atom->u.refname, ref->symref);
+	}
 }
 
 static const char *get_refname(struct used_atom *atom, struct ref_array_item *ref)
 {
-	if (ref->kind & FILTER_REFS_DETACHED_HEAD)
+	if (ref->kind & FILTER_REFS_DETACHED_HEAD) {
 		return get_head_description();
-	return show_ref(&atom->u.refname, ref->refname);
+	} else if (ref->special_tag_verify && atom->u.refname.option == R_NORMAL) {
+		const char * refname;
+
+		atom->u.refname.option = R_LSTRIP;
+		atom->u.refname.lstrip = 2;
+		refname = show_ref(&atom->u.refname, ref->refname);
+		atom->u.refname.option = R_NORMAL;
+		return refname;
+	} else {
+		return show_ref(&atom->u.refname, ref->refname);
+	}
 }
 
 static int get_object(struct ref_array_item *ref, int deref, struct object **obj,
@@ -1878,7 +1901,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
 
 			refname = branch_get_upstream(branch, NULL);
 			if (refname)
-				fill_remote_ref_details(atom, refname, branch, &v->s);
+				fill_remote_ref_details(atom, refname, branch, &v->s, ref);
 			else
 				v->s = xstrdup("");
 			continue;
@@ -1899,7 +1922,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
 			}
 			/* We will definitely re-init v->s on the next line. */
 			free((char *)v->s);
-			fill_remote_ref_details(atom, refname, branch, &v->s);
+			fill_remote_ref_details(atom, refname, branch, &v->s, ref);
 			continue;
 		} else if (atom_type == ATOM_COLOR) {
 			v->s = xstrdup(atom->u.color);
@@ -2641,6 +2664,7 @@ void pretty_print_ref(const char *name, const struct object_id *oid,
 	ref_item = new_ref_array_item(name, oid);
 	ref_item->kind = ref_kind_from_refname(name);
 	ref_item->flag = ref_flags;
+	ref_item->special_tag_verify = format->special_tag_verify;
 	if (format_ref_array_item(ref_item, format, &output, &err))
 		die("%s", err.buf);
 	fwrite(output.buf, 1, output.len, stdout);
diff --git a/ref-filter.h b/ref-filter.h
index edd9a3b6652..63c8d24a6fc 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -42,6 +42,7 @@ struct ref_array_item {
 	int flag;
 	unsigned int kind;
 	const char *symref;
+	int special_tag_verify;
 	struct commit *commit;
 	struct atom_value *value;
 	char refname[FLEX_ARRAY];
@@ -84,6 +85,7 @@ struct ref_format {
 
 	/* Internal state to ref-filter */
 	int need_color_reset_at_eol;
+	int special_tag_verify;
 };
 
 #define REF_FORMAT_INIT { .use_color = -1 }
diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh
index 10faa645157..85e2a653ed8 100755
--- a/t/t7030-verify-tag.sh
+++ b/t/t7030-verify-tag.sh
@@ -194,6 +194,29 @@ test_expect_success GPG 'verifying tag with --format' '
 	test_cmp expect actual
 '
 
+test_expect_success GPG 'verifying tag with --format="%(refname) %(symref)"' '
+	git tag -s -m bar annotated &&
+	git symbolic-ref refs/tags/symref refs/tags/annotated &&
+	sha=$(git rev-parse symref) &&
+	SP=" " &&
+	cat >expect <<-EOF &&
+	verify: annotated$SP
+	verify: symref annotated
+	verify: $sha$SP
+	EOF
+	git verify-tag --format="verify: %(refname) %(symref)" annotated symref $sha >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success GPG 'tag verify with --format="%(refname) %(symref)"' '
+	cat >expect <<-EOF &&
+	verify: annotated$SP
+	verify: symref annotated
+	EOF
+	git tag --verify --format="verify: %(refname) %(symref)" annotated symref >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success GPG 'verifying tag with --format="%(rest)" must fail' '
 	test_must_fail git verify-tag --format="%(rest)" "fourth-signed"
 '
-- 
gitgitgadget

      parent reply	other threads:[~2021-09-20  7:38 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-20  7:37 [PATCH 0/4] ref-filter: fix %(symref) for pretty_print_ref() ZheNing Hu via GitGitGadget
2021-09-20  7:37 ` [PATCH 1/4] refs: let repo_dwim_ref() learn get symref itself and ref flags ZheNing Hu via GitGitGadget
2021-09-20  7:37 ` [PATCH 2/4] ref-filter: provide ref_flags to pretty_print_ref() ZheNing Hu via GitGitGadget
2021-09-20  7:37 ` [PATCH 3/4] verify_tag: use repo_dwim_ref() to get ref fullname and ref_flags ZheNing Hu via GitGitGadget
2021-09-20  7:37 ` ZheNing Hu via GitGitGadget [this message]

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=d4e77765a8f5478c360fe78e72eb556ecdc326a5.1632123476.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=adlternative@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.