Software Versioning with Git

Git is the standard version control system used in ANNIE. A primary function of version control systems is to ensure reproducability in data processing and analysis. This means knowing which version you're using.

The describe option of git will produce a version string using the most recent tag, along with information about any commits or changes made subsequent to that tag.

The standard options to git describe for ANNIE software are:

git describe --abbrev=4 --dirty --always --tags
which will produce a result similar to:
Meaning that the code is two commits after the v1.0 tag, with the abbreviated object name (hash) of 73c0. (The 'g' is for "git".)

If tracked files have been modified subsequent to the most recent commit, the tag -dirty will be added to the end of the version string. Since these modifications have not been committed, and therefore not tracked, any output will be considered unreproduceable. We shouldn't expect to ever have a need to discuss a 'version' marked as such. It should also go without saying that if the commit is never pushed to the origin master, no one will ever be able to find it.

Tagging commits

A tag for version 2.3 of some software would be crated by

git tag -a v2.3 -m "Release v2.3" 
ANNIE standardizes on a lowercase 'v' for tags where the number before the point is an integer, and the number following the point is also an integer. (For example, 'v2.10' is a newer release than 'v2.2')

Then push your commit up to the origin (this isn't done by default) with:

git push origin --tags

Get a list of tagged commits with:

git tag -l

Check out a previously tagged commit with (for instance):

git checkout tags/v2.3

Version strings with C/C++ code and Makefiles

Your Makefile can be set to use a commandline-specified preprocessor macro to insert the git version string into your code as a constant.

Defining a Makefile variable as:

GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
you can use this variable in your CFLAGS variable with the -D option to insert the version string into your code as if it were set as a #define preprocessor macro.
CFLAGS= -g -Wall -Iinclude/ -DVERSION=\"$(GIT_VERSION)\" 

If your code has a line like:

const std::string myversion = VERSION;
it will be modified by the preprocessor to be
const std::string myversion = "v1.0-2-g73c0";
using the example from above.

Version strings with Python and

Python can run git directly at runtime with:

from subprocess import check_output
git_version = check_output("git describe --abbrev=4 --dirty --always --tags".split()).decode('utf-8').strip()

Version strings in C/C++ code built with (cython-based extensions):

Compiled C/C++ code built using (as would be the case for a cython-based extension) can combine the C/C++ method with the Python method by adding the preprocessor macro in the extra_compile_args option of the extension definition

extra_compile_args = ['-DVERSION=\"{version}\"'.format(version=git_version),]
after defining the python string git_version as shown above.