The --all
option means consider all tags and all branches and all other refs. As such, it always produces tags/string
or heads/name
or, e.g., remotes/origin/next
(or fails; see below).
If you expect the result to always be a tag, just check that it starts with tags/
.
If you want to force the result to always be a tag, even if that's a lightweight tag, but never a branch name, use --tags
instead of --all
.
Note, however, that --tags
can fail, if no tag works as a descriptive entity. This is even true for --all
, even if there are tags. For instance, an orphan commit created on a detached HEAD when there are no branch names will do the trick:
$ mkdir ttag
$ cd ttag
$ git init
Initialized empty Git repository in ...
$ echo test > README
$ git add README
$ git commit -m initial
[master (root-commit) 7e9de28] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ git checkout --detach
HEAD is now at 7e9de28 initial
$ git branch -d master
Deleted branch master (was 7e9de28).
$ git describe --all
fatal: No names found, cannot describe anything.
Here's a different example to show how --all
can fail even if there are tags:
$ cd .../git
$ git describe
v2.33.1-835-ge9e5ba39a7
$ git checkout --orphan dummy
Switched to a new branch 'dummy'
$ git commit -m for-describe-error
[dummy (root-commit) 06145997e1] for-describe-error
3989 files changed, 1384670 insertions(+)
create mode 100644 .cirrus.yml
create mode 100644 .clang-format
create mode 100644 .editorconfig
[tons of output snipped]
$ git describe --all
heads/dummy
HEAD is now at 06145997e1 for-describe-error
$ git describe --all
heads/dummy
$ git describe --all
fatal: No tags can describe '06145997e15516ce13b24d94ca70ecb7cec8863f'.
Try --always, or create some tags.
$ git checkout master
Warning: you are leaving 1 commit behind, not connected to
[snip warning I didn't really need since that was the idea]
To force git describe
not to fail, use --always
:
$ git describe --always
7e9de28
It's not really clear to me what your purpose in using --all
here was, but if you just want to know if the current commit has some tag, whether the tag is lightweight or annotated, use git describe --tags --exact-match
. This either:
- fails, because no tag matches; or
- succeeds and prints the tag name of the matching tag.
By redirecting stderr away and checking the status, you can tell if there was a tag:
if tag=$(git describe --tags --exact-match 2>/dev/null); then
... this commit is tagged ...
else
... this commit is not tagged ...
fi
and that seems to fit the text of your question, but makes me wonder why you were using --all
in the first place.
Note: to check whether a variable $v
holds something that starts with the given prefix, the case
statement is actually the short and sweet method:
case "$v" in
foo*) echo "prefixed with foo";;
bar*) echo "prefixed with bar";;
*) echo "not prefixed with foo or bar";;
esac
This works for a variable that might hold tags/*
or heads/*
.