list tags contained by a branch

Git

Git Problem Overview


How can I list tags contained by a given branch, the opposite of:

git tag --contains <commit>

Which "only list tags which contain the specified commit".

If something like this does not exist, how do I test whether a commit is contained by another commit so that I can script this?

I could do this:

commit=$(git rev-parse $branch)
for tag in $(git tag)
do
    git log --pretty=%H $tag | grep -q -E "^$commit$"
done

But I hope there is a better way as this might take a long time in a repository with many tags and commits.

Git Solutions


Solution 1 - Git

git tag --merged <branch>

From the man page:

--[no-]merged <commit>

Only list tags whose tips are reachable, or not reachable if --no-merged is used, from the specified commit (HEAD if not specified).

I believe this option was added quite recently - it definitely wasn't available back when the original question was posed and the above answers suggested. Since this thread is still the first hit in Google for the question I figured I'd throw it in for anyone who scrolls down to the bottom looking for an answer that involves less typing than the accepted answer (and for my own reference when I forget this answer again next week).

Solution 2 - Git

This might be close to what you want:

git log --simplify-by-decoration --decorate --pretty=oneline "$committish" | fgrep 'tag: '

But, the more common situation is to just find the most recent tag:

git describe --tags --abbrev=0 "$committish"
  • --tags will search against lightweight tags, do not use it if you only want to consider annotated tags.
  • Do not use --abbrev=0 if you want to also see the usual “number of ‘commits on top’ and abbreviated hash” suffix (e.g. v1.7.0-17-g7e5eb8).

Solution 3 - Git

to list all tags reachable on the current branch:

git log --decorate=full --simplify-by-decoration --pretty=oneline HEAD | \
sed -r -e 's#^[^\(]*\(([^\)]*)\).*$#\1#' \
       -e 's#,#\n#g' | \
grep 'tag:' | \
sed -r -e 's#[[:space:]]*tag:[[:space:]]*##'

Solution 4 - Git

I do not have enough reputation to comment on other people's posts, but this is in response to the answer and its comments at https://stackoverflow.com/a/7698213/2598329. In order to show all of the tags reachable by the current branch, including the tag on the HEAD commit, you can use the following:

git log --decorate --oneline | egrep '^[0-9a-f]+ \((HEAD, )?tag: ' | ssed -r 's/^.+tag: ([^ ]+)[,\)].+$/\1/g'

One caveat - I use super sed, so you may need to change my "ssed" to sed.

And for the hell of it, here it is in PowerShell:

git log --decorate --oneline | % { if ($_ -match "^[0-9a-f]+ \((HEAD, )?tag: ") { echo $_} } | % { $_ -replace "^.+tag: ([^ ]+)[,\)].+$", "`$1" }

-- -a

Solution 5 - Git

Windows-specific answer for anyone looking.

(Powershell has recently gone open-source & cross-platform so command given below will run on the systems other than Windows too.)

> NOTE: below is for old versions of git or for specific use cases!

For powershell:

git log --simplify-by-decoration --decorate --pretty=oneline "$committish" | Select-String 'tag: '

you can also use: -CaseSensitive flag for Select-String to make it case sensitive

For cmd:

git log --simplify-by-decoration --decorate --pretty=oneline | findstr -i "tag: "

you can remove -i to make the search case sensitive

> NOTE: For newer versions & cross-platform, cross-terminal as long as it supports git command:

git tag --merged <branchname>

you can use options like format, color, sort & many others with this. Check it all out here: https://git-scm.com/docs/git-tag

Solution 6 - Git

You could use this:

# get tags on the last 100 commits:
base_rev=master~100
end_rev=master
for rev in $(git rev-list $base_rev..$end_rev)
do 
    git describe --exact-match $rev 2> /dev/null
done

Solution 7 - Git

Here's how I list annotated tags matching a pattern (TAG_PREFIX*) in reverse chronological order. This recipe uses git-describe.

#!/usr/bin/env bash

tag=$(git describe --abbrev=0 --match TAG_PREFIX*)
until [ -z $tag ]; do
    echo $tag
    tag=$(git describe --abbrev=0 --match TAG_PREFIX* $tag^ 2>/dev/null);
done

This won't work if multiple tags matching the pattern point to the same commit. For that, here is another recipe that uses git-rev-list and git-tag to list all tags, matching TAG_PREFIX*, starting from a commit (HEAD in this example).

#!/usr/bin/env bash

git rev-list HEAD | while read sha1; do
    tags=( "$(git tag -l --points-at $sha1 TAG_PREFIX*)" )
    [[ ! -z ${tags[*]} ]] && echo "${tags[@]}" | sort -r
done

Solution 8 - Git

all answer only list tags, but if you want them in chronological order, you need to add --sort=taggerdate

or example:

 git tag --merged release/11.x --sort=taggerdate
studio-1.4
llvmorg-10-init
llvmorg-11-init
llvmorg-11.0.0-rc1
llvmorg-11.0.0-rc2
llvmorg-11.0.0-rc3
llvmorg-11.0.0-rc4
llvmorg-11.0.0-rc5
llvmorg-11.0.0-rc6
llvmorg-11.0.0

Solution 9 - Git

There is a git branch --contains (Git since 1.5.7, at least)

Solution 10 - Git

Efficient for large numbers of tags and gets easy format flexibility:

{ git rev-list --first-parent ${1:-HEAD}
  git for-each-ref --format='%(objectname) %(objecttype)  %(refname)
                             %(*objectname) *(%(objecttype)) %(refname)' 
} \
| awk '
  NF==1   { revs[$1]=1; next }
          { if ( $1 in revs ) print $1,$2,$3 }
'

which gets all refs, add refs/tags to the f-e-r to restrict it.

Solution 11 - Git

git describe (or some variant of it) might be what you're looking for.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontarsiusView Question on Stackoverflow
Solution 1 - GitJamHandyView Answer on Stackoverflow
Solution 2 - GitChris JohnsenView Answer on Stackoverflow
Solution 3 - GitFerry HubertsView Answer on Stackoverflow
Solution 4 - GitakutzView Answer on Stackoverflow
Solution 5 - GitMiKr13View Answer on Stackoverflow
Solution 6 - GitJared GrubbView Answer on Stackoverflow
Solution 7 - GitakhanView Answer on Stackoverflow
Solution 8 - GitWangView Answer on Stackoverflow
Solution 9 - Gitfork0View Answer on Stackoverflow
Solution 10 - GitjthillView Answer on Stackoverflow
Solution 11 - GitebneterView Answer on Stackoverflow