Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
+1 Interesting idea, I should try this. –  David Z Aug 8 '10 at 20:34

6 Answers 6

up vote 45 down vote accepted

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   
share|improve this answer
1  
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
2  
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
    
Explain what this is doing could be helpful... –  J. C. Leitão Jul 17 at 8:12

Since this question is frequently visited: Here is a blogposting on a really great batch 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 helpfull. Some classes seem to brake the code of the soul package, which is used to highlight the changes. I found it helpfull 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.

share|improve this answer
    
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

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.

share|improve this answer

For completeness, there's also git-latexdiff, here:

https://gitorious.org/git-latexdiff

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

share|improve this answer

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)
    shutil.copy(header, join(dir2, '%s.tex' % header_name))
    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)
    os.remove(header)
    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)
share|improve this answer
1  
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 ;)

share|improve this answer
1  
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.