Edited at

git diff で Office ファイルの差分を見る

入れたくないとは思っていても、止むに止まれぬ事情で Word, Excel, PowerPoint などのファイルを git レポジトリの中で管理することはありませんか?この記事では、Mac で Office ファイルの diff を取る方法を紹介します。Linux でも多分動くはず。


textconv

普通、バイナリファイルを git diff しても、変更内容がわかりません。ところが、git には textconv という、バイナリファイル(別にバイナリじゃなくてもいいんですが)をコマンドに渡した結果を diff に使う機能があります。ドキュメントには、JPEG の Exif 情報の diff を取る例等が載っています。


Office ファイルからのテキスト抽出

では、Office ファイルからテキストを抽出するにはどうすればいいでしょう?Windows の msysgit には astextplain というツールがついており、中では antiword, docx2txt, pdftotext などのツールを使っています。しかし、これでは Excel, PowerPoint ファイルに対応できません。

Office 2007 以降では Office Open XML という規格に基づいた .docx, .xlsx, .pptx というファイル形式が採用されています。これらは XML や画像ファイルを zip で固めたものなので、解凍すれば中身を見ることができます

~/bin/unopenxml というファイル名で、以下のようなスクリプトを置きます。(Qiita のコードブロックでは、拡張子がないとファイル名として表示されない?)

#!/bin/sh

unzip -c -a $1 | iconv -f utf-8 -t utf-8 -c | perl -pe 's/></>\n</g' | perl -p -0777 -e 's/ extracting: .*( inflating: |\Z)/\1/s'

こんな感じで unzip -c -a で zip の中身を取得し、XML に改行を入れて diff を読みやすくし、バイナリデータは無視するようにしています。~/bin/unopenxml some.pptx などとすると、ファイルの中身を見ることができます。


git diff で使う

これを git diff で使うには、以下のような設定をします。


~/.gitconfig

[diff "openxml"]

textconv = ~/bin/unopenxml


your-repo/.gitattributes

*.pptx diff=openxml

*.docx diff=openxml
*.xlsx diff=openxml

これで .pptx, .docx, .xlsx ファイルの diff が取れるようになりました。試してませんが .doc には antiword, .docx には docx2txt を使った方が、文字だけ見れて便利かもしれません。


Apache Tika を使う(2015/2/13 追記)

ajaxsys@github さんにコメントで教えていただきました。実行に少し時間がかかりますが、こっちの方が綺麗に diff が見えます!

ひとまず Mac の場合の手順を書きます。

brew install tika

~/bin/unopenxml というファイル名で、以下のようなスクリプトを置きます。"$1" とするのは、変なパス対策です。


~/bin/unopenxml

#!/bin/sh

tika -t "$1"

.gitconfig を編集し・・・


~/.gitconfig

[diff "openxml"]

textconv = ~/bin/unopenxml

レポジトリに .gitattributes を追加。


your-repo/.gitattributes

*.pptx diff=openxml

*.docx diff=openxml
*.xlsx diff=openxml