1 minute read

I often need project version information for documentation, About boxes, or website footers. Instead of hardcoding version numbers, I let git provide them automatically.

For my projects, git describe works best. It doesn’t modify sources on checkout and provides version information in a format usable in other git commands such as git diff.

Several ways exist to ask git for version information, including keyword expansion, described in this stackoverflow post.

git describe

git describe returns information about the working tree state or any particular commit. Several command line switches exist, but in most cases git describe --tags --always works fine. The command finds the most recent tag reachable from a commit. If the commit itself is pointed at by the tag, it shows the tag. Otherwise, it suffixes the tag name with the number of additional commits and the abbreviated object name.

% git describe --tags --always
v0.1.3-16-ge1b5922

Performance

Running git every time you need version information may not be ideal. When source code changes are rare and performance matters (e.g., production websites), get the information once, then store it. When changes are frequent and performance isn’t critical, querying git every time works fine.

Example

Sphinx makes it easy to create intelligent and beautiful documentation and is often used in the Python world. Project version information is stored in the Sphinx configuration file and embedded in auto-generated documentation. Since Sphinx is written in Python, getting version info is simple. First, add these lines to your docs/conf.py:

from subprocess import Popen, PIPE

def get_version():
"""
Returns project version as string from 'git describe' command.
"""
pipe = Popen('git describe --tags --always', stdout=PIPE, shell=True)
version = pipe.stdout.read()

if version:
    return version
else:
    return 'X.Y'

Then, replace hardcoded version and release values:

# The version info for the project you're documenting, acts as replacement for
# version and release, also used in various other places throughout the
# built documents.

# The short X.Y version.
version = get_version().lstrip('v').rstrip()
# The full version, including alpha/beta/rc tags.
release = version

Sphinx will now call git describe --tags --always every time documentation is generated and include your project version information in docs.

Comments