All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ref-filter: fix %(symref) for pretty_print_ref()
@ 2021-09-20  7:37 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
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: ZheNing Hu via GitGitGadget @ 2021-09-20  7:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, ZheNing Hu

Because pretty_print_ref() currently has no ref_item flag, but the
implementation of %(symref) need this flag, so git tag --verify or git
verify-tag cannot get the output of %(symref). Therefore, %(symref) will be
fixed in this patch series.

This bug was discovered by Peff here:
https://lore.kernel.org/git/YUO63qy2%2F5wibY4%2F@coredump.intra.peff.net/

on the other hand, git tag --verify --format="%(refname)" or git verify-tag
--forrmat="%(refname)" does not show the fullref name, but seems to be
similar to using %(refname:lstrip=2).

And git verify-tag --format="verify: %(refname)" c06b72d02` will output:
"verify: c06b72d02". They are wrong features, but because some scripts are
using them, so our current approach is to keep them.

ZheNing Hu (4):
  refs: let repo_dwim_ref() learn get symref itself and ref flags
  ref-filter: provide ref_flags to pretty_print_ref()
  verify_tag: use repo_dwim_ref() to get ref fullname and ref_flags
  ref-filter: let tag verify use %(refname:lstrip=2) by default

 builtin/tag.c         | 16 ++++++++-------
 builtin/verify-tag.c  |  9 ++++++++-
 object-name.c         |  6 +++---
 ref-filter.c          | 47 +++++++++++++++++++++++++++++++++----------
 ref-filter.h          |  4 +++-
 refs.c                | 15 +++++++++-----
 refs.h                |  8 +++++---
 t/t7030-verify-tag.sh | 23 +++++++++++++++++++++
 upload-pack.c         |  2 +-
 9 files changed, 98 insertions(+), 32 deletions(-)


base-commit: 8b7c11b8668b4e774f81a9f0b4c30144b818f1d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1042%2Fadlternative%2Fpretty-print-ref-symref-fix-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1042/adlternative/pretty-print-ref-symref-fix-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1042
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] refs: let repo_dwim_ref() learn get symref itself and ref flags
  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 ` 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
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: ZheNing Hu via GitGitGadget @ 2021-09-20  7:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, ZheNing Hu, ZheNing Hu

From: ZheNing Hu <adlternative@gmail.com>

expand_ref() can use to resolve a ref to its fullname, A symref will
also be resolved to the fullref name it refers to. But sometimes we
want get symref itself. So add a need_symref parameter to
repo_dwim_ref() and expand_ref(), which can help us get symref its
fullref name. At the same time, we add ref_flags parameter to
expand_ref() and repo_dwim_ref(), when it is set, it can get the
ref's flag from refs_resolve_ref_unsafe(), which can help us provide
ref's flags for interfaces like pretty_print_ref() later.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 object-name.c |  6 +++---
 refs.c        | 15 ++++++++++-----
 refs.h        |  8 +++++---
 upload-pack.c |  2 +-
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/object-name.c b/object-name.c
index fdff4601b2c..a8cb1d6ab14 100644
--- a/object-name.c
+++ b/object-name.c
@@ -803,7 +803,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,
 
 	if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) {
 		if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) {
-			refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0);
+			refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0, 0, 0);
 			if (refs_found > 0) {
 				warning(warn_msg, len, str);
 				if (advice_enabled(ADVICE_OBJECT_NAME_WARNING))
@@ -854,11 +854,11 @@ static int get_oid_basic(struct repository *r, const char *str, int len,
 
 	if (!len && reflog_len)
 		/* allow "@{...}" to mean the current branch reflog */
-		refs_found = repo_dwim_ref(r, "HEAD", 4, oid, &real_ref, 0);
+		refs_found = repo_dwim_ref(r, "HEAD", 4, oid, &real_ref, 0, 0, 0);
 	else if (reflog_len)
 		refs_found = repo_dwim_log(r, str, len, oid, &real_ref);
 	else
-		refs_found = repo_dwim_ref(r, str, len, oid, &real_ref, 0);
+		refs_found = repo_dwim_ref(r, str, len, oid, &real_ref, 0, 0, 0);
 
 	if (!refs_found)
 		return -1;
diff --git a/refs.c b/refs.c
index 8b9f7c3a80a..67618a09992 100644
--- a/refs.c
+++ b/refs.c
@@ -637,17 +637,19 @@ static char *substitute_branch_name(struct repository *r,
 }
 
 int repo_dwim_ref(struct repository *r, const char *str, int len,
-		  struct object_id *oid, char **ref, int nonfatal_dangling_mark)
+		  struct object_id *oid, char **ref, int nonfatal_dangling_mark,
+		  int *ref_flags, int need_symref)
 {
 	char *last_branch = substitute_branch_name(r, &str, &len,
 						   nonfatal_dangling_mark);
-	int   refs_found  = expand_ref(r, str, len, oid, ref);
+	int   refs_found  = expand_ref(r, str, len, oid, ref, ref_flags, need_symref);
 	free(last_branch);
 	return refs_found;
 }
 
 int expand_ref(struct repository *repo, const char *str, int len,
-	       struct object_id *oid, char **ref)
+	       struct object_id *oid, char **ref, int *ref_flags,
+	       int need_symref)
 {
 	const char **p, *r;
 	int refs_found = 0;
@@ -666,8 +668,11 @@ int expand_ref(struct repository *repo, const char *str, int len,
 					    fullref.buf, RESOLVE_REF_READING,
 					    this_result, &flag);
 		if (r) {
-			if (!refs_found++)
-				*ref = xstrdup(r);
+			if (!refs_found++) {
+				*ref = xstrdup(need_symref ? fullref.buf : r);
+				if (ref_flags)
+					*ref_flags = flag;
+			}
 			if (!warn_ambiguous_refs)
 				break;
 		} else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
diff --git a/refs.h b/refs.h
index 48970dfc7e0..1f977bdb188 100644
--- a/refs.h
+++ b/refs.h
@@ -152,15 +152,17 @@ int refname_match(const char *abbrev_name, const char *full_name);
 struct strvec;
 void expand_ref_prefix(struct strvec *prefixes, const char *prefix);
 
-int expand_ref(struct repository *r, const char *str, int len, struct object_id *oid, char **ref);
+int expand_ref(struct repository *r, const char *str, int len, struct object_id *oid, char **ref,
+	       int *ref_flags, int need_symref);
 int repo_dwim_ref(struct repository *r, const char *str, int len,
-		  struct object_id *oid, char **ref, int nonfatal_dangling_mark);
+		  struct object_id *oid, char **ref, int nonfatal_dangling_mark,
+		  int *ref_flags, int need_symref);
 int repo_dwim_log(struct repository *r, const char *str, int len, struct object_id *oid, char **ref);
 static inline int dwim_ref(const char *str, int len, struct object_id *oid,
 			   char **ref, int nonfatal_dangling_mark)
 {
 	return repo_dwim_ref(the_repository, str, len, oid, ref,
-			     nonfatal_dangling_mark);
+			     nonfatal_dangling_mark, 0, 0);
 }
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 
diff --git a/upload-pack.c b/upload-pack.c
index 6ce07231d3d..dfbdd6d9466 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -975,7 +975,7 @@ static int process_deepen_not(const char *line, struct string_list *deepen_not,
 	if (skip_prefix(line, "deepen-not ", &arg)) {
 		char *ref = NULL;
 		struct object_id oid;
-		if (expand_ref(the_repository, arg, strlen(arg), &oid, &ref) != 1)
+		if (expand_ref(the_repository, arg, strlen(arg), &oid, &ref, 0, 0) != 1)
 			die("git upload-pack: ambiguous deepen-not: %s", line);
 		string_list_append(deepen_not, ref);
 		free(ref);
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/4] ref-filter: provide ref_flags to pretty_print_ref()
  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 ` 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 ` [PATCH 4/4] ref-filter: let tag verify use %(refname:lstrip=2) by default ZheNing Hu via GitGitGadget
  3 siblings, 0 replies; 5+ messages in thread
From: ZheNing Hu via GitGitGadget @ 2021-09-20  7:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, ZheNing Hu, ZheNing Hu

From: ZheNing Hu <adlternative@gmail.com>

pretty_print_ref() creates a ref_item through new_ref_array_item(),
but such ref_item does not set its flag member, this means that %(symref)
will not be processed in populate_value().

So provide ref_flags parameter to pretty_print_ref() and verify_tag().
pretty_print_ref() has two callers: cmd_verify_tag(), verify_tag(),
let for_each_tag_name() use read_ref_full() instread of read_ref() to
generate the ref_flags and pass to pretty_print_ref(); However,
cmd_verify_tag() needs to be modified later to support providing ref_flags
to pretty_print_ref().

At the same time, let verify_tag() pass "ref" instread of "name" to
gpg_verify_tag() and pretty_print_ref(), which can help pretty_print_ref
get fullref name.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 builtin/tag.c        | 15 ++++++++-------
 builtin/verify-tag.c |  2 +-
 ref-filter.c         |  3 ++-
 ref-filter.h         |  2 +-
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/builtin/tag.c b/builtin/tag.c
index 065b6bf093e..ce5678d179f 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -83,7 +83,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
 }
 
 typedef int (*each_tag_name_fn)(const char *name, const char *ref,
-				const struct object_id *oid, void *cb_data);
+				const struct object_id *oid, void *cb_data, int ref_flags);
 
 static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
 			     void *cb_data)
@@ -92,16 +92,17 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
 	struct strbuf ref = STRBUF_INIT;
 	int had_error = 0;
 	struct object_id oid;
+	int ref_flags;
 
 	for (p = argv; *p; p++) {
 		strbuf_reset(&ref);
 		strbuf_addf(&ref, "refs/tags/%s", *p);
-		if (read_ref(ref.buf, &oid)) {
+		if (read_ref_full(ref.buf, RESOLVE_REF_READING, &oid, &ref_flags)) {
 			error(_("tag '%s' not found."), *p);
 			had_error = 1;
 			continue;
 		}
-		if (fn(*p, ref.buf, &oid, cb_data))
+		if (fn(*p, ref.buf, &oid, cb_data, ref_flags))
 			had_error = 1;
 	}
 	strbuf_release(&ref);
@@ -109,7 +110,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
 }
 
 static int collect_tags(const char *name, const char *ref,
-			const struct object_id *oid, void *cb_data)
+			const struct object_id *oid, void *cb_data, int unused_flags)
 {
 	struct string_list *ref_list = cb_data;
 
@@ -143,7 +144,7 @@ static int delete_tags(const char **argv)
 }
 
 static int verify_tag(const char *name, const char *ref,
-		      const struct object_id *oid, void *cb_data)
+		      const struct object_id *oid, void *cb_data, int ref_flags)
 {
 	int flags;
 	struct ref_format *format = cb_data;
@@ -152,11 +153,11 @@ static int verify_tag(const char *name, const char *ref,
 	if (format->format)
 		flags = GPG_VERIFY_OMIT_STATUS;
 
-	if (gpg_verify_tag(oid, name, flags))
+	if (gpg_verify_tag(oid, ref, flags))
 		return -1;
 
 	if (format->format)
-		pretty_print_ref(name, oid, format);
+		pretty_print_ref(ref, oid, format, ref_flags);
 
 	return 0;
 }
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index f45136a06ba..403f2080efa 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -71,7 +71,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
 		}
 
 		if (format.format)
-			pretty_print_ref(name, &oid, &format);
+			pretty_print_ref(name, &oid, &format, 0);
 	}
 	return had_error;
 }
diff --git a/ref-filter.c b/ref-filter.c
index 93ce2a6ef2e..6c51ef25136 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2632,7 +2632,7 @@ int format_ref_array_item(struct ref_array_item *info,
 }
 
 void pretty_print_ref(const char *name, const struct object_id *oid,
-		      struct ref_format *format)
+		      struct ref_format *format, int ref_flags)
 {
 	struct ref_array_item *ref_item;
 	struct strbuf output = STRBUF_INIT;
@@ -2640,6 +2640,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;
 	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 c15dee8d6b9..edd9a3b6652 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -140,7 +140,7 @@ void setup_ref_filter_porcelain_msg(void);
  * name must be a fully qualified refname.
  */
 void pretty_print_ref(const char *name, const struct object_id *oid,
-		      struct ref_format *format);
+		      struct ref_format *format, int ref_flags);
 
 /*
  * Push a single ref onto the array; this can be used to construct your own
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/4] verify_tag: use repo_dwim_ref() to get ref fullname and ref_flags
  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 ` ZheNing Hu via GitGitGadget
  2021-09-20  7:37 ` [PATCH 4/4] ref-filter: let tag verify use %(refname:lstrip=2) by default ZheNing Hu via GitGitGadget
  3 siblings, 0 replies; 5+ messages in thread
From: ZheNing Hu via GitGitGadget @ 2021-09-20  7:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, ZheNing Hu, ZheNing Hu

From: ZheNing Hu <adlternative@gmail.com>

Since verify-tag cannot currently use %(symref) correctly, we need
to get the ref flags from pretty_print_ref() caller. So use
repo_dwim_ref() in cmd_verify_tag() to get fullref name and ref flags
and pass to pretty_print_ref(), which can help us fix %(symref)
feature.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 builtin/verify-tag.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index 403f2080efa..efc8282782a 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -59,6 +59,8 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
 	while (i < argc) {
 		struct object_id oid;
 		const char *name = argv[i++];
+		char *refname;
+		int ref_flags;
 
 		if (get_oid(name, &oid)) {
 			had_error = !!error("tag '%s' not found.", name);
@@ -70,8 +72,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))
+			name = refname;
 		if (format.format)
-			pretty_print_ref(name, &oid, &format, 0);
+			pretty_print_ref(name, &oid, &format, ref_flags);
 	}
 	return had_error;
 }
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/4] ref-filter: let tag verify use %(refname:lstrip=2) by default
  2021-09-20  7:37 [PATCH 0/4] ref-filter: fix %(symref) for pretty_print_ref() ZheNing Hu via GitGitGadget
                   ` (2 preceding siblings ...)
  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
  3 siblings, 0 replies; 5+ messages in thread
From: ZheNing Hu via GitGitGadget @ 2021-09-20  7:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Jeff King, ZheNing Hu, ZheNing Hu

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-09-20  7:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 4/4] ref-filter: let tag verify use %(refname:lstrip=2) by default ZheNing Hu via GitGitGadget

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.