Generate an informative version name using Git

TL;DR

How do you generate an informative version name like 1.0.0-1-gd64d using git?

git describe --abbrev=4 --dirty --always --tags

What is git describe?

Git - git-describe Documentation:

NAME
git-describe - Give an object a human readable name based on an available ref

DESCRIPTION
The command finds the most recent tag that is reachable from a commit. If the tag points to the commit, then only the tag is shown. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit. The result is a “human-readable” object name which can also be used to identify the commit to other git commands.

Explanation

git describe --abbrev=4 --dirty --always --tags
  • --abbrev=4: Use 4 digits or as many digits as needed to form a unique object name.
  • --dirty: If the working tree has local modification “-dirty” is appended to the result.
  • --always: Show uniquely abbreviated commit object as fallback.
  • --tags: Instead of using only the annotated tags, use any tag found in refs/tags namespace.

Examples

gitGraph
   commit id: "ab27"
   commit id: "e9a9" tag: "v1.0.0"

Running git describe after the latest commit is tagged with 1.0.0:

$ git describe --abbrev=4 --dirty --always --tags
1.0.0 # returns the latest tag
gitGraph
   commit id: "ab27"
   commit id: "e9a9" tag: "v1.0.0"
   commit id: "d64d"

Running git describe after commit d64d is made since the 1.0.0 release:

$ git describe --abbrev=4 --dirty --always --tags
1.0.0-1-gd64d # suffixes with additional commits info

Here, the suffix -1-gd64d means we are 1 commit after version 1.0.0, d64d is the prefix of the current commit id, and the g here stands for git.

gitGraph
   commit id: "ab27"
   commit id: "e9a9" tag: "v1.0.0"
   commit id: "d64d"
   commit id: "Uncommitted" type: HIGHLIGHT

If some uncommitted changes are made after d64d, running git describe:

$ git describe --abbrev=4 --dirty --always --tags
1.0.0-1-gd64d-dirty # suffixed "-dirty" for uncommitted changes

References