git describe Command: Version Strings in CI
git describe produces a version string by finding the most recent tag reachable from a commit.
git describe is the standard way to turn commit state into a version like v1.2.0-5-gabc1234. It is a favorite in CI for stamping builds with a meaningful, sortable identifier.
Common flags
--tags- consider lightweight tags too, not just annotated ones--always- fall back to a short SHA when no tag is reachable--abbrev=N- set the number of SHA hex digits in the suffix (0 hides it)--dirty[=<mark>]- append a marker if the working tree has uncommitted changes--long- always include the commit count and SHA suffix--match <pattern>- only consider tags matching a glob
Example
# Robust version that never fails, even on an untagged commit
VERSION="$(git describe --tags --always --dirty)"
echo "version=${VERSION}"In CI
git describe fails with "fatal: No names found" when no tags are present or the clone is too shallow to reach one. Combine --tags --always so it degrades to a SHA, and ensure tags are fetched (fetch-depth: 0 and --tags) so the nearest tag is reachable.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
- uses: actions/checkout@v4
with:
fetch-depth: 0 # history, tags, and git describe all need this
- run: |
git rev-parse --is-shallow-repository # expect false
git rev-parse --abbrev-ref HEAD # prints HEAD when detachedKey takeaways
- git describe --tags --always never fails: it returns a SHA when no tag is found.
- It needs tags fetched and enough history, so deepen shallow CI clones.
- --dirty flags builds made from a modified working tree.