I keep most of my LaTeX source files under the revision control system Git.
Git is opinionated software. It allows you to do many things, but others run counter to its dogmas. In particular, Git does not modify source files.
Other systems do. For example, you can ask Subversion to replace the placeholder $Revision in the committed source file with the latest revision number. This is useful for displaying revision numbers or dates in your LaTeX documents, for example.
From Git’s perspective, modification of source file is pure evil. Not only is this feature absent from Git, but the very request betokens moral corruption.
From Git’s perspective, the client programme (in this case, LaTeX) is responsible for including revision information in the output. Git humbly makes that information available. But it does not modify the source.
Stephan Hennig’s vc bundle consists of a number of scripts that extract revision information from various version control systems, including Git, and make it available as LaTeX macros. The information is taken from a separate, automatically generated input file vc.tex, so that the main LaTeX source file remains untouched by Git.
This shifts the problem to the generation of vc.tex. I’ve played around with various solutions based on Makefiles, and here is my current setup.
The vc.tex file is automatically generated and defines three LaTeX macros. Typically, it looks like this:
%%% This file is generated by Makefile. %%% Do not edit this file! %%% \gdef\GITAbrHash{f61c739} \gdef\GITAuthorDate{Fri May 13 10:34:51 2011 +0200} \gdef\GITAuthorName{Thore Husfeldt}
The main LaTeX source includes the vc.tex file in the preamble and can now freely use these macros. For example, the revision information can be included in a footnote on the title page.
\documentclass{article} ... \input{vc.tex} ... \begin{document} \maketitle \let\thefootnote\relax \footnotetext{Base revision~\GITAbrHash, \GITAuthorDate, \GITAuthorName.} ...
The responsibility of producing an up-to-date vc.tex rests on the Makefile:
latexfile = main all: $(latexfile).pdf $(latexfile).pdf : $(latexfile).tex vc.tex while (pdflatex $(latexfile) ; \ grep -q "Rerun to get cross" $(latexfile).log ) do true ; \ done vc.tex: .git/logs/HEAD echo "%%% This file is generated by Makefile." > vc.tex echo "%%% Do not edit this file!\n%%%" >> vc.tex git log -1 --format="format:\ \\gdef\\GITAbrHash{%h}\ \\gdef\\GITAuthorDate{%ad}\ \\gdef\\GITAuthorName{%an}" >> vc.tex
The interesting rule is the last one. It runs git log
to produce vc.code. The hardest thing for me was to get the dependencies right. I think I’ve got it now. The input file vc.tex needs to be regenerated whenever it predates the last commit. As far as I understand the Git internals, the modification time of .git/logs/HEAD should give me a reliable timestamp for when the last commit happened, so I made my rule for vc.tex depend on that.
Of course, it’s a cheap operation, so we could generate vc.tex anew every time we run pdflatex. But then every call to make would recompile the source (because vc.tex has changed). To avoid that, we could leave vc.tex out of the dependencies for $(latexfile).pdf. But then a commit (which modifies the revision number but not any source files) would not lead to an automatic recompile. The LaTeX document would only display new revision information whenever it is edited after that revision.
If there’s a cleaner way of checking for “is vc.tex outdated compared to the Git repository”, please tell me.
TODO: Make the LaTeX document reflect that it corresponds to uncommitted edits after the latest revision. This should be doable by comparing the modification times of the LaTeX source files and .git/logs/HEAD. A cruder way is to let git status tell the Makefile if working directory is “clean”.
UPDATE (21 Feb 2012): Since this post was written, various other approaches have appeared. (Thanks to the commenters for pointing them out.) The idea of using a post-commit hook instead of a Makefile is now on CTAN: gitinfo package.