結論: latexdiff-vcを使う

$ latexdiff-vc -e utf8 --git --flatten --force -d diff -r HEAD test.tex
[alias]
	ldiff = !sh -c 'latexdiff-vc -e utf8 --git --flatten --force -d diff -r "${1:-HEAD}" test.tex && cd diff && latexmk' -

仮定

TeXLive2015(以上)を使います。古いとlatexdiff-vcが入っていないので、自分でインストールする必要があります。

僕の環境では、

  • LATEXDIFF 1.1.0 (Algorithm::Diff 1.15 so, Perl v5.18.2)
  • LATEXDIFF-VC 1.1.0
  • git version 1.9.1

でした。latexdiffのバージョンが古いと--flattenが上手く動作せず、gitのバージョンが相当古いとエイリアスが動かないみたいです。

できること

diffの画像

Gitなどのバージョン管理システムで管理されたLaTeXファイルの差分を良い感じにPDFで出力できます。

2017年1月現在この方法をググるとややこしいスクリプトが色々出てきますが、latexdiff-vcというのが便利になってたので以下ではそれについて書きます。

前準備

  • (重要) Bib(La)TeXを使っている方は、 .bblファイルもコミットしてください。
    • .bblファイルは文献情報の入った.bibファイルやスタイルを示す.bstファイルを元に自動生成される(La)TeXファイルです。latexdiffが上手くdiffをとるにはこれを生成した状態でなければならず、さらにコミット間のdiffをとるにはこれがコミットされていないといけません。man latexdiff-vc にも.bblファイルはコミットした方が良いと書いてあります。
  • 日本語がメインのファイルを管理している場合、「latexdiff 日本語」などでググって適切な前処理をしてください。単語境界の設定と、-t CFONTによる見栄えの調整が必要かもしれません。また、tlmgr updateなどで壊れるかもしれないので注意してください。
  • 各ファイルはUTF-8でエンコーディングされているとします。違う場合はオプション引数を変えて下さい。ファイルのエンコーディングはnkf --guess <file>などで分かります。

結論(再掲)

まず./diff/ディレクトリを作ります。 あとで説明する--flattenで読み込まれない画像があったり、自分用にスタイルファイルやクラスファイルを作っている場合は./diff/の中にも用意する必要があります。 たとえば./mystyle.sty./diff/test.texからでは読めないので、cd diff && ln -s ../mystyle.styなどとシンボリックリンクを貼ってあげるなどすると良いと思います。

その上で元のディレクトリに戻って、このコマンドを実行してください。大元のファイル名はtest.texだとしていますが、ここは適宜変更する必要があります。

$ latexdiff-vc -e utf8 --git --flatten --force -d diff -r HEAD test.tex

これで「今あるファイル」と「直前にコミットしたファイル(HEAD)」のdiffが./diff/test.texに出力されます。あとはこれをlatexmkなりなんなりでコンパイルすればPDFになります。

test.texの中でincludeなどをしていても引数はtest.texのみで大丈夫です。勝手に判断してくれます。

また、.gitconfigに次のように記述するとgit ldiffでdiffのPDFが作れるようになります。git ldiff HEAD~1みたいにも使えます。

[alias]
        ldiff = !sh -c 'latexdiff-vc -e utf8 --git --flatten --force -d diff -r "${1:-HEAD}" test.tex && cd diff && latexmk' -

ただしこのコマンドはレポジトリ依存なので、~/.gitconfigに書くのではなく、レポジトリの中に.gitconfigファイルを作り、git config --local include.path ../.gitconfigすることでローカルの.gitconfigも認識してもらうようにするのが良いでしょう。

また、このコマンドはlatexmkでコンパイルすることを前提としています。 違う方は書き換えて使ってください。 適切に~/.latexmkrcを設定していない場合、これだとPDFが出力されないかもしれません。 その場合は適宜--pdfなどのオプションを足すか、~/.latexmkrcを書いて下さい。

解説

latexdiff-vcはバージョン管理システムの元でlatexdiffを使うためのラッパです。 Git専用ではなく、SVNやMercurialでも使えます。 詳しくはmanページを見て下さい。

latexdiff-vc

latexdiff-vc [ latexdiff-options ] [ latexdiff-vc-options ] -r [rev1] [-r rev2]  file1.tex [ file2.tex ...]

という形で使えます。元々のコマンドは

$ latexdiff-vc -e utf8 --git --flatten --force -d diff -r HEAD test.tex

でした。以下オプションについて説明します。

  • -e utf8: エンコーディングです。実はデフォルトがUTF-8なので無くてもいいです。これが唯一latexdiffに渡されるオプションです。
  • --git: Gitで管理されていることを示します。これがない場合勝手に推論してくれるので実は無くてもいいです。
  • --flatten: \include\input、あるいはBibTeX使って\bibliographyしているものを全部展開して1ファイルとして扱うためのオプションです。これはlatexdiff-vcのオプションです。順番を間違えるとlatexdiffのオプションだと解釈されるときがあるので注意。
  • --force: 最終的にできる差分ファイルの上書きを強制します。
  • -d diff: diffという名前のディレクトリの中に結果を出力します。これが無いとその場に結果を出力してしまい、latexmkしにくいです。
  • -r HEAD: どのコミットと比較するか指定します。ここでは例としてHEADにしていますが、HEAD~1などにもできます。.gitconfig版ではここをオプション引数にしており、git ldiff HEAD~2などとすることで自由に選ぶことができます。

また、Gitのエイリアスに書いてあるびっくりマークは引数を処理するためのものです。詳しくはこちら。最後のハイフン(ダッシュ)はshの引数であり、実行されるコマンドの引数を示す変数を通常通り$1から始めさせるためにつけます。詳しくはshのmanページの-cオプションの所に書いてあります。

応用

  • どのコミットか示すためにGitのタグも使えるので、たとえば先生に提出する度にタグを付けておくと、提出の間に何回コミットしても大丈夫なので便利。
  • rev2のオプションも指定することで、2つのコミット間のdiffもとれます。
  • 数式周りでたまに変な挙動をするらしいですが、そのときはlatexdiff--math-markupオプションを使うと良いようです。

参考