Shell - check if a git tag exists in an if/else statement
Why so complicated? Here’s a dead-simple solution (based on cad106uk’s approach further down the page):
version=1.2.3
if [ $(git tag -l "$version") ]; then
echo yes
else
echo no
fi
It is not necessary to compare the output of git tag -l
with the version number, because the output will be empty if the version is not found. Therefore it’s sufficient to test if there’s any output at all.
Note: The quotes around $version
are important to avoid false positives. Because if $version
is empty for some reason, git tag -l
would just list all tags, and the condition would always be true.
You could use git rev-parse
instead:
if GIT_DIR=/path/to/repo/.git git rev-parse $1 >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
git rev-list
invokes graph walking, where git rev-parse
would avoid it. The above has some issues with possibly looking up an object instead of a tag. You can avoid that by using ^{tag}
following the tag name, but this only works for annotated tags and not lightweight tags:
if GIT_DIR=/path/to/repo/.git git rev-parse "$1^{tag}" >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
@Lassi also points out that if your tag name begins with a -
, then it might get interpreted as an option instead. You can avoid that issue by looking for refs/tags/$1
instead. So in summary, with the rev-parse
version, you can look for refs/tags/$1
to get both lightweight and annotated tags, and you can append a ^{tag}
to the end to enforce an annotated tag (refs/tags/$1^{tag}
).
Also, as mentioned before by @forvaidya, you could simply list the tags and grep for the one you want:
if GIT_DIR=/path/to/repo/.git git show-ref --tags | egrep -q "refs/tags/$1$"
then
echo "Found tag"
else
echo "Tag not found"
fi
You can also use git tag --list
instead of git show-ref --tags
:
if GIT_DIR=/path/to/repo/.git git tag --list | egrep -q "^$1$"
then
echo "Found tag"
else
echo "Tag not found"
fi
If you know the tag though, I think it's best just to just look it up via rev-parse
. One thing I don't like about the egrep
version is that it's possible you could have characters that could get interpreted as regex sequences and either cause a false positive or false negative. The rev-parse
version is superior in that sense, and in that it doesn't look at the whole list of tags.
Another option is to use the pattern feature of git show-ref
:
if GIT_DIR=/path/to/repo/.git git show-ref --tags "refs/tags/$1" >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
This avoids the extra egrep
invocation and is a bit more direct.