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