Git でバイナリファイル判定

Git でエンコーディングチェック の続きです。

git diff でテキストかバイナリかを判定する方法がないかなと書きましたが、うまいオプションがありました。

それは --name-only の代わりに --numstat を使うことです。

$ git init hoge
$ cd hoge
$ echo -e "\xe3\x81\xbb\xe3\x81\x92" >utf8.txt
$ echo -e "\x82\xd9\x82\xb0" >shiftjis.txt
$ cp /usr/share/gitweb/static/git-logo.png .
$ git add .
$ git diff --cached --name-only --diff-filter=ACM
git-logo.png
shiftjis.txt
utf8.txt
$ git diff --cached --numstat --diff-filter=ACM
-	-	git-logo.png
1	0	shiftjis.txt
1	0	utf8.txt

このように Git がバイナリファイルと考えているものについては、先頭に数字ふたつではなく - ふたつを表示してくれます。 .gitattributes による指定も考慮してくれますので都合がよいです。

$ echo "shiftjis.txt binary" >.gitattributes
$ git add .
$ git diff --cached --numstat --diff-filter=ACM
1       0       .gitattributes
-       -       git-logo.png
-       -       shiftjis.txt
1       0       utf8.txt

ということで pre-commit スクリプトを更新しました:
https://gist.github.com/2361136/c6e49adffe6847f3936a65fdbcef48d092071900

これを .git/hooks/pre-commit に置いておけば git commit だけでエンコーディングチェックをしつつバイナリファイルもコミットできます。

$ git commit -m 'Commit with binary and sjis text files'
[master (root-commit) 875203e] Commit with binary and sjis text files
 4 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 .gitattributes
 create mode 100644 git-logo.png
 create mode 100644 shiftjis.txt
 create mode 100644 utf8.txt
$ cp shiftjis.txt 'shift jis.txt'
$ git add .
$ git commit -m 'Another sjis text file'
shift jis.txt: shiftjis
Commit aborted! (allowed encodings: ascii utf8)

2012/04/18 19:46:00 JST