ようやく実現できたのでやり方をメモ。
設定ファイルで拡張子に基づくフィルタリングをすればOK。
ProGitの情報によるとリポジトリから取ってくるときをsmudge、リポジトリに突っ込むときをcleanと呼ぶらしい。
以下はリポジトリ内のソースファイルがUTF-8 BOM有、改行コードがLFCRの場合の設定例。文字コード変換はnkfを使っています。
WindowsのVisualStudioに合わせると上記設定が望ましいが、Linux環境でgccを使うにはBOM無しにして、改行コードをLFにする必要がある。
まず.gitconfigファイルに以下を追加する
[filter "fixencoding"]
clean = “/usr/local/bin/nkf -w8 -Lw”
smudge = “/usr/local/bin/nkf -w -Lu”
これでsmudgeでUTF-8 BOM無し/LF、cleanでUTF-8 BOM有り/LFCRとなる。
これだけではダメで、フィルタ処理をかけるファイルを指定する必要が有る。
gitの管理フォルダである.gitがあるトップディレクトリに.gitattributesファイルを以下の内容で作成し、git checkout -fする必要が有る。
*.c filter=fixencoding
*.cpp filter=fixencoding
*.cxx filter=fixencoding
*.h filter=fixencoding
*.hxx filter=fixencoding
*.txt filter=fixencoding
Makefile filter=fixencoding
/usr/share/git-core/templates/info/attributes
を作って上記内容を書いておくとclone時に.git/info以下にコピーされてgit cloneしただけで文字コード変換が動くようになる。
動かすにあたって問題となったのはgitでチェックアウトしただけで編集されたことになってしまうファイルが多々発生したことです。原因はいろいろあったのですが
リポジトリインデックス内のファイル文字コードがバラバラだった(BOM無しファイルが紛れ込んでいた とか)
ファイル内の文字に半角カナがあるとダメらしい。
ファイル内の文字に機種依存文字(実際にあったのは丸数字)があるとダメらしい。
git statusなどで編集が有ったかどうかはインデックス内の状態と比較するからcleanして元々の状態と変わってしまうと当然チェックアウトしただけで編集されたと勘違いされてしまうファイルができてしまう ということですね。
WEB DB Press Vol.50で解説されていたgitの内部データ構造を知ってようやく理解できました。
Subverisonだと文字コードをうまく変換する機構も無いのでgitをかましてやるのが便利ですね。