# Unify annotated and non-annotated tags

6 messages from 2017-11-10 to 2017-12-23. Participants: anatoly techtonik, Igor Djordjevic, Junio C Hamano.
Thread: https://gitlist.dev/t/47153

## anatoly techtonik, 2017-11-10 10:58

Subject: Unify annotated and non-annotated tags
Message-ID: <CAPkN8x+MELCnttE+xptKzYXsYPWqbiE59LABrwNBhFroayc+wQ@mail.gmail.com>
URL: https://gitlist.dev/e/CAPkN8x%2BMELCnttE%2BxptKzYXsYPWqbiE59LABrwNBhFroayc%2BwQ%40mail.gmail.com

```
Hi,

It is hard to work with Git tags, because on low level hash
of non-annotated tag is pointing to commit, but hash for
annotated tag is pointing to tag metadata.

On low level that means that there is no way to get commit
hash from tag in a single step. If tag is annotated, you need
to find and parse ^{} string of show-ref, if not, then look for
string without ^{}.

So, why not just make all tags work the same so that every
tag has its own hash and you need to dereference it in the
same way to get commit hash?

This way I could get all commit hashes with just:

    git show-ref --tags -d | grep "\^{}"

or abandon ^{} completely and show commit hashes on -d:

    git show-ref --tags --dereference

-- 
anatoly t.

```

## Igor Djordjevic, 2017-11-11 01:46

Subject: Re: Unify annotated and non-annotated tags
Message-ID: <ec4be1c2-a0cc-cec8-a566-06c11c8abe06@gmail.com>
URL: https://gitlist.dev/e/ec4be1c2-a0cc-cec8-a566-06c11c8abe06%40gmail.com
In-Reply-To: <CAPkN8x+MELCnttE+xptKzYXsYPWqbiE59LABrwNBhFroayc+wQ@mail.gmail.com>

```
Hi Anatoly,

On 10/11/2017 11:58, anatoly techtonik wrote:
> It is hard to work with Git tags, because on low level hash
> of non-annotated tag is pointing to commit, but hash for
> annotated tag is pointing to tag metadata.
> 
> On low level that means that there is no way to get commit
> hash from tag in a single step. If tag is annotated, you need
> to find and parse ^{} string of show-ref, if not, then look for
> string without ^{}.

That is not quite true, as you can always dereference any tag 
(annotated or not) using "<tag>^0" notation, see git-rev-parse[1]:

  "As a special rule, <rev>^0 means the commit itself and is used when 
  <rev> is the object name of a tag object that refers to a commit 
  object."
 
> So, why not just make all tags work the same so that every
> tag has its own hash and you need to dereference it in the
> same way to get commit hash?
> 
> This way I could get all commit hashes with just:
> 
>     git show-ref --tags -d | grep "\^{}"
> 
> or abandon ^{} completely and show commit hashes on -d:
> 
>     git show-ref --tags --dereference
>
Depending on what you would _exactly_ like to do, you could get all 
tagged commit hashes like this:

	git rev-list --tags --no-walk

Note that each commit will be listed only once, even if more tags 
(annotated or not) point to it.

If you would like to mimic output of "git show-ref", repeating 
commits for each tag pointing to it and showing full tag name as 
well, you could do something like this, for example:

	for tag in $(git for-each-ref --format="%(refname)" refs/tags)
	do
		printf '%s %s\n' "$(git rev-parse $tag^0)" "$tag"
	done


Hope that helps a bit.

Regards, Buga

[1] https://git-scm.com/docs/git-rev-parse#git-rev-parse-emltrevgtemegemHEADv1510em

```

## Junio C Hamano, 2017-11-11 02:06

Subject: Re: Unify annotated and non-annotated tags
Message-ID: <xmqqh8u1efh5.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqqh8u1efh5.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <ec4be1c2-a0cc-cec8-a566-06c11c8abe06@gmail.com>

```
Igor Djordjevic <igor.d.djordjevic@gmail.com> writes:

> If you would like to mimic output of "git show-ref", repeating 
> commits for each tag pointing to it and showing full tag name as 
> well, you could do something like this, for example:
>
> 	for tag in $(git for-each-ref --format="%(refname)" refs/tags)
> 	do
> 		printf '%s %s\n' "$(git rev-parse $tag^0)" "$tag"
> 	done
>
>
> Hope that helps a bit.

If you use for-each-ref's --format option, you could do something
like (pardon a long line):

git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname)' refs/tags

without any loop, I would think.



```

## Igor Djordjevic, 2017-11-11 02:50

Subject: Re: Unify annotated and non-annotated tags
Message-ID: <59bd5e13-01a5-6c39-04bf-c60cab4004e5@gmail.com>
URL: https://gitlist.dev/e/59bd5e13-01a5-6c39-04bf-c60cab4004e5%40gmail.com
In-Reply-To: <xmqqh8u1efh5.fsf@gitster.mtv.corp.google.com>

```
On 11/11/2017 03:06, Junio C Hamano wrote:

> Igor Djordjevic <igor.d.djordjevic@gmail.com> writes:
> 
>> If you would like to mimic output of "git show-ref", repeating 
>> commits for each tag pointing to it and showing full tag name as 
>> well, you could do something like this, for example:
>>
>> 	for tag in $(git for-each-ref --format="%(refname)" refs/tags)
>> 	do
>> 		printf '%s %s\n' "$(git rev-parse $tag^0)" "$tag"
>> 	done
>>
>>
>> Hope that helps a bit.
> 
> If you use for-each-ref's --format option, you could do something
> like (pardon a long line):
> 
> git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname)' refs/tags
> 
> without any loop, I would think.

... and I did have a feeling it should be possible in a single Git 
command :P Thanks.

```

## anatoly techtonik, 2017-11-23 07:31

Subject: Re: Unify annotated and non-annotated tags
Message-ID: <CAPkN8xJU74N_kYL9f2v_vuk3C3omhYaz7uPMzbanEU=RTEPOYg@mail.gmail.com>
URL: https://gitlist.dev/e/CAPkN8xJU74N_kYL9f2v_vuk3C3omhYaz7uPMzbanEU%3DRTEPOYg%40mail.gmail.com
In-Reply-To: <xmqqh8u1efh5.fsf@gitster.mtv.corp.google.com>

```
On Sat, Nov 11, 2017 at 5:06 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Igor Djordjevic <igor.d.djordjevic@gmail.com> writes:
>
>> If you would like to mimic output of "git show-ref", repeating
>> commits for each tag pointing to it and showing full tag name as
>> well, you could do something like this, for example:
>>
>>       for tag in $(git for-each-ref --format="%(refname)" refs/tags)
>>       do
>>               printf '%s %s\n' "$(git rev-parse $tag^0)" "$tag"
>>       done
>>
>>
>> Hope that helps a bit.
>
> If you use for-each-ref's --format option, you could do something
> like (pardon a long line):
>
> git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname)' refs/tags
>
> without any loop, I would think.

Thanks. That helps.

So my proposal is to get rid of non-annotated tags, so to get all
tags with commits that they point to, one would use:

git for-each-ref --format='%(*objectname) %(refname)' refs/tags

For so-called non-annotated tags just leave the message empty.
I don't see why anyone would need non-annotated tags though.
-- 
anatoly t.

```

## anatoly techtonik, 2017-12-23 13:33

Subject: Re: Unify annotated and non-annotated tags
Message-ID: <CAPkN8x+tFDSum1jqgm6Q+Z2YS9BdGttyruc4rAywqinzbP033g@mail.gmail.com>
URL: https://gitlist.dev/e/CAPkN8x%2BtFDSum1jqgm6Q%2BZ2YS9BdGttyruc4rAywqinzbP033g%40mail.gmail.com
In-Reply-To: <xmqqh8u1efh5.fsf@gitster.mtv.corp.google.com>

```
On Sat, Nov 11, 2017 at 5:06 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Igor Djordjevic <igor.d.djordjevic@gmail.com> writes:
>
>> If you would like to mimic output of "git show-ref", repeating
>> commits for each tag pointing to it and showing full tag name as
>> well, you could do something like this, for example:
>>
>>       for tag in $(git for-each-ref --format="%(refname)" refs/tags)
>>       do
>>               printf '%s %s\n' "$(git rev-parse $tag^0)" "$tag"
>>       done
>>
>>
>> Hope that helps a bit.
>
> If you use for-each-ref's --format option, you could do something
> like (pardon a long line):
>
> git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname)' refs/tags
>
> without any loop, I would think.

This doesn't work with git 1.9.1
https://github.com/rtfd/readthedocs.org/pull/3441#issuecomment-353567756
When it was added? I searched through GitHub and docs, but can't find any
historical records.

-- 
anatoly t.

```
