Git + LaTeX + gitinfo = ❤

TL;DR

You can add a nice “DRAFT” watermark to your paper with additional info from git. See the result (click to download the PDF):

Grab the code on GitHub, where you can find a working example (with some dummy text).

The problem: keeping track of printed drafts

While working on a paper I have expanded some LaTeX macros originally created by my colleagues Matteo Lissandrini (aka Kuzeko) and Davide.

We had a LaTeX macro to add a “DRAFT” watermark to the paper, with the compilation date and time: something that would add a big dark-red top-secret-style stamp to the side of the paper saying:
“DRAFT 2017‑01‑24 23:20:51”.

However I was having some trouble when reviewing printed copies: was I reading an old version or the latest? When was this version compiled? Was it a corresponding to a specific commit or did it have some modification that had not yet be pushed to the repository? (Of course we keep papers we are writing under version control).

I needed a way to add to the draft watermark some more info, in particular I wanted:

  • some version number that would be available for any commit, for which I could use the abbreviated commit hash;
  • the date and time of the last commit;
  • the compilation/current date and time of the paper, these were already available with the \today and \currenttime LaTeX macros;
  • a symbol indicating if there were some new uncommitted modifications with respect to the last commit.

The problem was getting the information about the commit from git and let LaTeX know about them. The tricky part is that in principle LaTeX does not know anything about git – or any other version control system (VCS) for that matter – so, it has no native way to access the information stored in your VCS.

Gitinfo to the rescue

To get the information I needed from git I have found the gitinfo2 package. The logic behind it is simple: whenever you do a commit, checkout or merge, git executes a post-{commit,checkout,merge} hook. These hooks produce a file with all the information about the last commit called gitHeadInfo.gin. The gitinfo package provides a series of LaTeX macros that can be used in the document and upon compilation the actual values are read from gitHeadInfo.gin and printed in the final document.

Here’s an example of how gitHeadInfo.gin file may look like:

Using the macros provided by gitinfo \gitAbbrevHash, \gitCommitterDateDisplay I was able to get something like:
DRAFT (v. 94364f8, 2017‑01‑24) 2017‑01‑24 23:44:18

A symbol for git in LaTeX

Finally I wanted a symbol for representing when modifications were made to the repository, but not yet commited that is some visual cue for when the repo has some new changes with respect to the last commit. You can find the same idea when looking at several themes for oh-my-zsh: if you are within a directory which is part of a version control repository your prompt can change to show which branch you are on, if there are uncommited changes and other useful info.

When in a repo the last commit or checkout left uncommitted changes in the repository, the repo is said to be in a dirty state, this is also the term that gitinfo2 uses[1]There are different schools of thought, though..

There many symbols for representing a change in a git repo, many use the plus-minus (±), and I really like the alternate-key symbol (⎇), but using Unicode characters in my LaTeX source has proven to create much more difficulties than what was worth[2]While in principle it is simple to switch from PDFLaTeX to XeTeX it was completely messing with some of my Tikz graphs and other complex contraptions I had in my paper, so I needed to stick with … Continue reading. Using an image or a special font (such as octicons by GitHub) was not as portable as I would have hoped. In the end I used the existing LaTeX symbol \hookrightarrow (rightwards arrow with hook) and played around with it to get the following symbol git branch symbol in LaTeX: a rightwards arrow with hook rotated counterclockwise by 45 degrees and scaled up 1.2 times.

gitinfo2 provides macros that signal if the repository is dirty and eventually I was able to produce something like this:
DRAFT (v. git branch symbol in LaTeX: a rightwards arrow with hook rotated counterclockwise by 45 degrees and scaled up 1.2 timesd314f84, 2017‑10‑25) 2017‑01‑25 14:28:54

Caveat Emptor

The gitinfo hooks are executed only when a git operation (commit, checkout or merge) is perfomed. For this reason modifying and saving the files in the repo does not automatically trigger the update of githeadInfo.gin. The documentation warns the user in this respect. Howerever, I have solved the problem adding to the LaTeX Makefile a pre-build target that triggers the update of githeadInfo.gin.

If you use a different build system, check out how you can configure it to launch one of the hooks (which you can find in ${repo_base_dir}/.git/hooks/).

Packaging everything togheter + extras

Finally I have added a couple of extra features.

To visualize the DRAFT stamp all you you need is to put the command \draft in your preamble.

A IsDraft toggle

The etoolbox package provides the possibility to define toggles. A toggle is a global switch that you can use to do stuff like this:

In this way when the paper is in draft status, it will show my name, while when it is ready for sending it will just show “Blind submission”.

A long option for \draft

If you want to display the commit time as well as the date you can invoke the draft command in this way \draft{long}.

Conclusions

You can add a nice “DRAFT” watermark to your paper with additional info from git. See the result (click to download the PDF):

The only dependencies for this macro are the gitinfo and etoolbox packages.
Grab the code on GitHub, where you can find a working example.


The feature image is from schlosser.info.

References

References
1 There are different schools of thought, though.
2 While in principle it is simple to switch from PDFLaTeX to XeTeX it was completely messing with some of my Tikz graphs and other complex contraptions I had in my paper, so I needed to stick with PDFLaTeX.