# Using latexdiff with git

I'd like to be able to use latexdiff with git. At the moment I have an alias in my .gitconfig file for a word-based diff:

[alias]
wdiff = diff --color-words

but is it possible to make an alias that will use latexdiff then compile the output and open the created dvi/pdf file?

Probably the best approach to this is using git difftool, but has anyone already made an appropriate script?

The most complete and general solution today is probably git-latexdiff, here:

https://gitlab.com/git-latexdiff/git-latexdiff

The script internally checks out the full tree for the specified revisions, and calls latexdiff with the --flatten option (or can call latexpand), hence this works if the document is split into multiple .tex files.

The script contains many special-cases to make it work for as many cases as possible (it received contributions from more than 10 contributors, most of them being "make it work for my use-case too").

Note: I'm the main author.

• This answer deserves to be much higher up. git-latexdiff is a brilliant tool that does everything and requires only a make install to install and then you can simply git latexdiff HEAD~1 – Azrael3000 Feb 21 '15 at 16:56
• I did not try the alternatives, but this one worked smoothly right away. Nice work! – BenC Oct 19 '15 at 15:36
• Impressive tool. Note that I had to apt-get install asciidoc to make the installation script word on my machine. – NoBackingDown Oct 9 '17 at 13:47

Do you mean something like the following?

~/bin/git-latexdiff

#!/bin/bash
TMPDIR=$(mktemp -d /tmp/git-latexdiff.XXXXXX) latexdiff "$1" "$2" >$TMPDIR/diff.tex
pdflatex -interaction nonstopmode -output-directory $TMPDIR$TMPDIR/diff.tex
evince $TMPDIR/diff.pdf rm -rf$TMPDIR

~/.gitconfig

[difftool.latex]
cmd = git-latexdiff \"$LOCAL\" \"$REMOTE\"
[difftool]
prompt = false
[alias]
ldiff = difftool -t latex

You can then use the diff by running git ldiff HEAD~1, for example.

• Brilliant! Thanks, it works perfectly. The only changes I made was to use batchmode instead of nonstopmode to suppress some of the output (can look at the log file if need be) and to replace the last line with trap $(rm -rf$TMPDIR) EXIT – Simon Aug 10 '10 at 2:44
• Minor point: the script should trap signals to make sure $TMPDIR is deleted in case it receives a signal like SIGINT. – Christian Lindig Feb 23 '12 at 12:49 • Any easy way to copy across auxiliary files, like bibtex files? – naught101 Mar 19 '13 at 4:44 • Am I right in my understanding that this only really works for documents made from a single .tex file? – drfrogsplat Aug 29 '14 at 4:18 • @drfrogsplat please see an answer below for the git-latexdiff that should also work for multiple files. – Azrael3000 Feb 21 '15 at 16:57 There is another option which has become available since the answers here were written. I think that it will be preferred by some as it does not require any additional packages. Beginning in version 1.0.1, latexdiff has come with a version of latexdiff-vc which supports git. Simply running latexdiff-vc [ latexdiff-options ] [ latexdiff-vc-options ] -r [rev1] [-r rev2] file1.tex [ file2.tex ...] will run latexdiff on the specified versions from its best guess of the version control system in use. The --git option specifies that it should assume git. This can also be specified by running latexdiff-git, which has git as the default VCS. The option --pdf will run pdflatex (and bibtex if necessary) on the output. See the latexdiff manual for more information. Since this question is frequently visited: Here is a blog-posting on a really great bash script here. The maintainer says: ## Latexbatchdiff A bash script that utilizes the brilliant perl script “latexdiff” in a latex project that is maintained in git. It does support multiple pdf files, and it automatically creates the pdf. You can get a 'diff' between every commit and your current version, easily. It is very helpful. Some classes seem to brake the code of the soul package, which is used to highlight the changes. I found it helpful to add to my preamble this code to prevent any difficulties: \providecommand{\DIFadd}[1]{{\protect\color{blue}#1}} %DIF PREAMBLE \providecommand{\DIFdel}[1]{{\protect\color{red}\protect\scriptsize{#1}}} What's been added, is printed in blue, what has been deleted, in small red type. • Nice to see that so many people write scripts to this kind of job in all kinds of languages :) – Paul Hiemstra Feb 10 '12 at 11:48 • Apparently the project was moved there. – BenC Oct 19 '15 at 9:40 • lol the blog post references this thread. Meta. – lindhe Jan 3 '16 at 17:21 • As of today (22/Nov/2018), this project has not seen any activity since 2013. – Krishna Nov 22 '18 at 17:16 • @Krishna It works! – Keks Dose Nov 22 '18 at 18:34 I recently created a rather nice Python script which works both on Mercurial and git repositories. It also supports bibtex and diffing against files that are not yet in the repository. See this blog post for more details. The code can be downloaded from bitbucket: hg clone https://bitbucket.org/paulhiemstra/scm-latexdiff or download a tar ball. Some examples of the usage of the script on the command line: # for hg scm-latexdiff 4:spam.tex scm-latexdiff 4:spam.tex 6:spam.tex # for git scm-latexdiff 87213:spam.tex scm-latexdiff 87213:spam.tex 97123:spam.tex # You can also diff against non-commited (local) files scm-latexdiff local:spam.tex scm-latexdiff 2:spam.tex local:spam.tex The script should work on all platforms that support Python. If you have any suggestions, or bug reports, you can submit an new issue in the issue tracker. EDIT: A new version of the program now also supports multi-file latex documents. Especially for reports and books this can be important. Note that you need a recent version of latexdiff (2007) to be able to work with multi-file documents. To install the program, clone the repository or download a tar ball and go to the directory where you extracted/cloned the tool and type (note that you probably need to be root for this to work): python setup.py install To install to a non-standard directory tree (e.g. in your home directory) use --prefix: python setup.py install --prefix=/home/spam/ Do remember to add /home/spam/lib/python2.x/site-packages/ to your PYTHONPATH environment variable. • This bitbucket repository does not seem to be updated since 2012. Can you please confirm if the intention is to actively maintain this project? – Krishna Nov 22 '18 at 17:13 • @Krishna I have no plans regarding expansion of this tool. But it probably still works.... – Paul Hiemstra Nov 25 '18 at 19:49 This does not work in a documment with included files. I have a very inelegant python script (see below). Any ideas to improve it? ~/.gitconfig ldiff = !latexdiff-git.py latexdiff-git.py #!/usr/bin/env python # A git integration for latex diff # Using git diff will be faster but more work. import os from os.path import join, split import sys import shutil import logging import tempfile from optparse import OptionParser if __name__ == '__main__': parser = OptionParser() parser.add_option("-o", "--output", dest="output", default='diff', help="name of the output file") parser.add_option("-t", "--temp", dest="tmp_path", default=None, help="name of the temporary folder") #parser.add_option("-1", "--one", dest="", default=None, help="Uses pdflatex in the oldest commit") (options, args) = parser.parse_args() if not options.tmp_path: options.tmp_path = tempfile.mkdtemp() pdf = '%s.pdf' % options.output texout = '%s.tex' % options.output basedir = os.getcwd() dir1 = join(options.tmp_path, '1') dir2 = join(options.tmp_path, '2') if len(args) == 2: commit1 = args[0] commit2 = 'HEAD' texin = args[1] else: commit1 = args[0] commit2 = args[1] texin = args[2] texin = '%s.tex' % texin file1 = join(dir1, texin) file2 = join(dir2, texin) shutil.rmtree(options.tmp_path, ignore_errors = True) (hdl, header) = tempfile.mkstemp() print('Temporary path: %s' % options.tmp_path) print('Temporary file: %s' % header) os.system(r'echo \\begin{verbatim} >> %s' % header) os.system('echo %s >> %s' % (texin, header)) os.system(r'echo \\end{verbatim} >> %s' % header) os.system(r'echo \\hrule >> %s' % header) os.system(r'echo \\begin{verbatim} >> %s' % header) os.system('echo From: %s >> %s' % (commit1, header)) shutil.copytree(basedir, dir1) os.chdir(dir1) os.system('git checkout %s' % commit1) os.system('git log -1 >> %s' % header) os.system(r'echo \\end{verbatim} >> %s' % header) os.system(r'echo \\hrule >> %s' % header) os.system(r'echo \\begin{verbatim} >> %s' % header) os.system('echo To: %s >> %s' % (commit2, header)) shutil.copytree(basedir, dir2) os.chdir(dir2) os.system('git checkout %s' % commit2) os.system('git log -1 >> %s' % header) os.system(r'echo \\end{verbatim} >> %s' % header) (hdl, header_name) = split(header) os.system('latexdiff --flatten %s %s > %s' % (join(dir1, texin), join(dir2, texin), texout)) #os.system(r"sed -i 's/$/\/\/\//g' %s " % header)
os.system(r"sed -i 's/begin{document}/begin{document}\\include{%s}/g' %s " % (header_name, texout))
os.system('pdflatex %s' % texout)
shutil.copy(texout, basedir)
shutil.copy(pdf, basedir)
os.chdir(basedir)
shutil.rmtree(options.tmp_path, ignore_errors = True)
if os.name == 'nt':
os.filestart(pdf)
elif os.name == 'posix':
os.system('/usr/bin/xdg-open %s' % pdf)
else:
os.system('open %s' % pdf)
• You could talk a look at my Python solution I show in my post. It tries to split all functionality up into separate functions to create more easy to read and maintainable code. – Paul Hiemstra Feb 10 '12 at 11:57

rcs-latexdiff tool can do that. It can make a latexdiff of different versions of a same file within a RCS repository. It also manages included files.

The basic usage is:

$rcs-latexdiff [OPTIONS] filename old_commit new_commit So for example,$ rcs-latexdiff paper.tex HEAD~1 HEAD

creates an output file diff.tex that is the latexdiff of the paper.tex file for the two last revisions. Then, it's up to you to compile the output file using your favorite compiler.

So, in your case, if you want to get a pdf highlighting changes between submitted version of a paper and its camera-ready version, you could do:

$rcs-latexdiff report.tex branch_submitted_version branch_camera_ready_version$ rubber -d diff.tex

These commands create a diff.tex (highlighting differences between two branches) and rubber generates a pdf.

The ultimate goal of this tool is to support all the different RCS software. At the moment, it only supports SVN and Git. You can find install instructions on Github page. Feel free to use, reports bugs and contribute ;)

• Thanks for telling us about your tool. Although it is definitely relevant, I noticed that you posted this answer verbatim in reply to another question, which is poor form and a mild form of advertising, which can come off as spam. Please tailor your replies so they address the specific question. – Ryan Reich Jul 23 '12 at 16:20
• Done. This post try to answer the git related question and propose a way to generate a diff between two commits. I also edited the other post, based on SVN. Thanks for your comment ;) – driquet Jul 24 '12 at 8:01
• Isn't this basically equivalent to the ten-line solution proposed by amonakov? The case which is difficult to handle with the current tools is multiple tex sources (think include/input). In my opinion you should focus on it if you are writing a tool for this task. – Federico Poloni Jul 24 '12 at 11:22
• rcs-latexdiff manages included files. It looks recursively for includes and inputs, get the included content and replace the initial LaTeX instruction by the content. And it also works for other RCS than Git (only SVN at the moment ; Mercurial is coming). The idea was to use only one tool for all RCS software. At my office, people use either SVN, Git or Mercurial, so it's easier to explain once how to make a latexdiff for different revisions. – driquet Jul 24 '12 at 12:46

use this in case you are on windows, no installment, just a simple bat script It works perfectly on windows10, miktex2.9:

https://github.com/redreamality/git-latexdiff