先週、プロジェクト内のWordドキュメントの変更履歴を確認する必要があった。git log -p contract.docx を実行してみると、ターミナルに意味不明なバイナリ文字の羅列が表示された。どのバージョンでどの条項が追加されたのか、誰がどの箇所を修正したのか——まったく追跡できなかった。
Gitはテキストファイルにはとてもパワフルだが、バイナリファイル(PDF、Word、SQLite、画像など)に対しては、デフォルトでは Binary files differ と表示するだけで止まってしまう。この問題を解決できる、あまり知られていない機能がある:Git Diff Driverだ。
Git Diff Driverとは?
Git Diff Driverは、Gitのデフォルトエンジンの代わりに外部コマンドを指定してdiff処理を行う仕組みだ。diff driverが設定されたファイルをGitが検出すると、そのコマンド——通常はバイナリファイルをテキストに変換するツール——を呼び出し、テキスト出力を通常のdiffと同様に処理する。
動作の流れは以下の通りだ:
- Gitが
report.pdfの変更を検出する - Gitが設定を読み込む:
*.pdfファイルはpdfという名前のdiff driverを使用 - Gitが
pdfdriverを呼び出し、pdftotextコマンドでファイルをプレーンテキストに変換する - Gitが2つのバージョンのテキスト出力を通常ファイルと同様にdiffする
結果として、Binary files differ の代わりに、追加・削除・修正されたテキストの内容が正確に表示される。
設定はたった2ステップだ:
~/.gitconfig(またはリポジトリの.git/config)にdriverを定義する.gitattributesでそのdriverをファイルの種類に割り当てる
実践:ファイルの種類ごとの設定
1. PDFファイル — pdftotext を使用
poppler-utils パッケージから pdftotext をインストールする:
# Ubuntu/Debian
sudo apt install poppler-utils
# macOS
brew install poppler
~/.gitconfig に追加する:
[diff "pdf"]
textconv = pdftotext -layout -enc UTF-8 - -
リポジトリの .gitattributes に定義する:
*.pdf diff=pdf
テストしてみる:
git diff HEAD~1 HEAD -- report.pdf
Binary files differ の代わりに、PDFで追加または削除されたテキストがターミナルに正確に表示される。契約書や技術仕様書のレビュー時にこれを最もよく使う——Acrobatを開いてバージョンを比較する必要なく、ターミナル上で直接確認できる。
2. Word/DOCXファイル — pandoc を使用
2つの選択肢がある。フォーマット処理が優れているため、pandoc の方が好みだ:
# Ubuntu/Debian
sudo apt install pandoc
# macOS
brew install pandoc
~/.gitconfig にdriverを定義する:
[diff "docx"]
textconv = pandoc --to=plain
よりシンプルにテキストを抽出したい場合は、docx2txt を使う:
pip install docx2txt
[diff "docx"]
textconv = python3 -c "import docx2txt,sys; print(docx2txt.process(sys.argv[1]))"
.gitattributes に追加する:
*.docx diff=docx
*.doc diff=docx
3. SQLiteファイル — SQLにdumpしてdiffする
SQLiteデータベースはバイナリだが、SQLにdumpすれば内容は完全に読み取れる。小さなシェルスクリプトを書き、/usr/local/bin/git-sqlite-diff に保存する:
#!/bin/bash
sqlite3 -readonly "$1" .dump
chmod +x /usr/local/bin/git-sqlite-diff
~/.gitconfig に追加する:
[diff "sqlite3"]
textconv = git-sqlite-diff
.gitattributes でデータベースファイルに割り当てる:
*.db diff=sqlite3
*.sqlite diff=sqlite3
*.sqlite3 diff=sqlite3
diffすると、GitはSQL INSERT/CREATE TABLEの変更を表示する——データベースクライアントを開かずに直接レビューできる。実用的な注意点:数十MBのデータベースを .dump すると、数百万行のINSERTになることがある。その場合、スキーマだけをdumpすれば構造の変更箇所を把握するのに十分だ:
#!/bin/bash
sqlite3 -readonly "$1" .schema
4. 画像ファイル — exiftool でメタデータをdiffする
画像のピクセルをdiffすることはできないが、メタデータはdiffできる:サイズ、作成日、カメラ設定、GPSなど。exiftool をインストールする:
# Ubuntu/Debian
sudo apt install libimage-exiftool-perl
# macOS
brew install exiftool
~/.gitconfig に追加する:
[diff "image"]
textconv = exiftool
.gitattributes に定義する:
*.png diff=image
*.jpg diff=image
*.jpeg diff=image
*.gif diff=image
*.webp diff=image
ピクセルサイズやカラープロファイルの詳細情報を確認したい場合は、ImageMagickの identify を使う:
sudo apt install imagemagick
# ~/.gitconfig の中:
[diff "image"]
textconv = identify -verbose
グローバル設定 vs リポジトリ単位の設定
driverの設定を行う場所は2つある:
~/.gitconfig:マシン上のすべてのリポジトリに適用——PDF、DOCX、画像には最適。どのプロジェクトでも共通して使えるツールのため.git/config:現在のリポジトリにのみ適用——そのプロジェクト固有のdriverに適切
.gitattributes ファイルはチーム全体が恩恵を受けられるようリポジトリにcommitすべきだ。driver定義については、各自が必要なツールをインストールし、自分のマシンで設定する。
典型的なプロジェクトの完全な .gitattributes ファイル:
# バイナリファイルのdiff driver
*.pdf diff=pdf
*.docx diff=docx
*.doc diff=docx
*.db diff=sqlite3
*.sqlite diff=sqlite3
*.sqlite3 diff=sqlite3
*.png diff=image
*.jpg diff=image
*.jpeg diff=image
*.gif diff=image
*.webp diff=image
git log と git show でも使用可能
diff driverは git diff だけでなく、他のコマンドでも動作する:
# 履歴の変更を確認する
git log -p -- report.pdf
# 2つのブランチを比較する
git diff main..feature-branch -- database.db
# 特定のコミットのファイル内容を確認する
git show abc1234:report.pdf | pdftotext - -
重要な点:driverはdiffを表示するときにのみ実行され、Gitのファイル保存方法には影響しない。ファイルはオブジェクトストアにバイナリ形式のまま保存される——完全に安全だ。
以前、間違ったブランチにforce pushして重要なコードを失ったことがある——それ以来、共有ブランチで何か操作する前に必ず履歴を細かく確認するようにしている。だからこそ、バイナリファイルのdiffが読めることは単なる便利さにとどまらない——コミットメッセージを見て推測するのではなく、何をpushするか正確に把握できる。
よくあるエラーの対処法
- driverが動作しない:
gitconfigのdriver名が.gitattributesの名前と一致しているか確認する(大文字・小文字を区別)。例:diff=pdfは[diff "pdf"]と一致している必要がある - ツールが見つからない:GitはツールがPATHに存在する必要がある。ターミナルで直接コマンドを実行して確認してみること
- 大きなSQLiteで出力が多すぎる:
.dumpを.schemaに変更してテーブル構造のみを表示する - PDFのエンコードエラー:pdftotextコマンドに
-enc UTF-8を追加すれば解決
まとめ
Gitはデフォルトでバイナリファイルをブラックボックスとして扱う——変更があったことはわかるが、何が変わったかはわからない。Diff Driverはその制限を打ち破る:PDF、Word、SQLite、画像——すべてが通常のコードファイルと同様にレビューできる。
一度設定すれば、ずっと使える。チームで作業している場合は、すぐに .gitattributes ファイルをリポジトリにcommitしよう——各自が必要なツールを自分のマシンにインストールするだけで、チーム全体が恩恵を受けられる。
