Skip to content
LatchkeyLatchkey home

git describe --tags --dirty: Version Strings in CI

git describe --tags --dirty produces a version like v1.4.2-3-gabc1234-dirty: nearest tag, commits since, short SHA, plus a -dirty suffix if the tree has uncommitted changes.

Build pipelines lean on git describe to stamp artifacts with a readable version. The flags that matter in CI are --tags (count lightweight tags), --always (fall back to a SHA), and --dirty (flag uncommitted changes).

What it does

git describe finds the most recent tag reachable from HEAD and appends the number of commits since it and the abbreviated SHA. --tags also considers lightweight (non-annotated) tags. --dirty appends a marker if the working tree differs from HEAD. --always falls back to a bare SHA when no tag is reachable.

Common usage

Terminal
git describe --tags --dirty
# always produce something, even with no tags
git describe --tags --always --dirty
# match only release tags
git describe --tags --match "v[0-9]*"
# just the long form (always tag-count-sha)
git describe --tags --long

Options

FlagWhat it does
--tagsUse lightweight tags too, not only annotated
--dirty[=<mark>]Append -dirty (or <mark>) if the tree is modified
--alwaysFall back to an abbreviated SHA if no tag is found
--longAlways show tag-count-gSHA, even on an exact tag
--match <pattern>Only consider tags matching the glob
--abbrev=<n>Number of hex digits in the short SHA

In CI

Shallow clones usually omit tags, so git describe fails with "No names found". Fetch tags first: git fetch --tags --unshallow, or set fetch-depth: 0 in actions/checkout. Add --always so a tagless repo still yields a SHA instead of erroring the whole build.

Common errors in CI

"fatal: No names found, cannot describe anything." means no reachable tag, almost always a shallow clone without tags; fetch tags or add --always. "fatal: No annotated tags can describe ..." means you have only lightweight tags; add --tags. "fatal: Not a valid object name HEAD" appears on an empty repo with no commits.

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.

.github/workflows/ci.yml
- 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 detached

Frequently asked questions

git describe --tags --dirty: Version Strings in CI?
Build pipelines lean on git describe to stamp artifacts with a readable version. The flags that matter in CI are --tags (count lightweight tags), --always (fall back to a SHA), and --dirty (flag uncommitted changes).
What it does?
git describe finds the most recent tag reachable from HEAD and appends the number of commits since it and the abbreviated SHA. --tags also considers lightweight (non-annotated) tags. --dirty appends a marker if the working tree differs from HEAD. --always falls back to a bare SHA when no tag is reachable.
In CI?
Shallow clones usually omit tags, so git describe fails with "No names found". Fetch tags first: git fetch --tags --unshallow, or set fetch-depth: 0 in actions/checkout. Add --always so a tagless repo still yields a SHA instead of erroring the whole build.
Common errors in CI?
"fatal: No names found, cannot describe anything." means no reachable tag, almost always a shallow clone without tags; fetch tags or add --always. "fatal: No annotated tags can describe ..." means you have only lightweight tags; add --tags. "fatal: Not a valid object name HEAD" appears on an empty repo with no commits.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card