Windows/Linux両環境で動作するC言語ソースの一元管理をGitで行う

5月 2nd, 2010 by tune Leave a reply »

gitでリポジトリからのチェックアウト時に文字コードを変換する » tune webの続きです。
【未解決】VisualStudioとgccでコンパイルできるソースのエンコーディング » tune webでも書きましたが、問題はVisualStudioはUTF-8 BOM有のみ、gccはUTF-8 BOM無しのみ扱え、両者で問題なく扱える文字コードが存在しない事でした。gitにあるsmudge/cleanを使うとチェックアウト/ステージ時に任意のフィルタを通すことができ、BOMの除去をここでやれば出来そうなのですが、文字コード変換ソフトのnkfではBOMの有り無し以外も書き変わってしまうことがあるため実用に使えなかったのがこれまででした。

git smudge/cleanはPro Git – Pro Git 7.2 Git のカスタマイズ Git の属性に詳しく解説されています。
git smudge/cleanの設定は前の日記に書きましたが、ここでも引用しておきます。

まず.gitconfigファイルに以下を追加

[filter "fixbom"]
clean = “/usr/bin/bom_util -a”
smudge = “/usr/bin/bom_util -d”

これでsmudgeでUTF-8 BOM無し、cleanでUTF-8 BOM有りになります。

これだけではダメで、フィルタ処理をかけるファイルを指定する必要が有ります。
gitの管理フォルダである.gitがあるトップディレクトリに.gitattributesファイルを以下の内容で作成し、git checkout -fします。

*.c filter=fixbom
*.h filter=fixbom

/usr/share/git-core/templates/info/attributes を作って上記内容を書いておくとclone時に.git/info以下にコピーされてgit cloneしただけで文字コード変換が動くようになります。

上記で指定している、BOMをつけ外しするプログラムは結局自作しました。単にファイル先頭のBOMを検知して追加・削除をするだけです。ハマったこととしてgit smudge/cleanのデータは標準入力から渡され、標準出力へ書いた内容で差し替えられます。外部コマンドとして起動されるのかと思っていましたが異なるようです。
BOMをつけ外しするプログラムを下に貼っておきます。(gistはこちら→gist: 386410 – GitHub)

#!/usr/bin/ruby

require "optparse"

mode = :help

opt = OptionParser.new
opt.on("-a", "Add BOM"){|v| mode = :add}
opt.on("-d", "Delete BOM"){|v| mode = :delete}
opt.parse!(ARGV)

case mode
when :add
 STDOUT.binmode
       lines = readlines
       unless lines[0] =~ /^\M-o\M-;\M-?/ then
               print "\xEF\xBB\xBF"
       end
       print lines

when :delete
 STDOUT.binmode
       lines = readlines
 lines[0].sub!(/^\xEF\xBB\xBF/, '')
 print lines

when :help
       STDERR.puts opt.help
end

VisualStudioでの開発をメインにしているので、リポジトリ内のソースをUTF-8 BOM有、改行コードをLFCRにして運用しています。
これでLinux環境での開発がひとつやりやすくなりました。

入門Git 入門git 実用Git

Advertisement