torutkのブログ

ソフトウェア・エンジニアのブログ

改行コードの扱いを検討

分散バージョン管理ツールでGitを使いたくなるのは、ファイル名の文字コードが違うOS間で日本語のファイルを共有するようなリポジトリを扱うときです。Windows OSとLinux OSと同じGitリポジトリを使用するとき、Gitであればファイル名に日本語を使っても問題ありませんが、Mercurialでは片方のOSで作成した日本語ファイル名をもう片方のOSで読むことができません(文字化け)。Bazaarが衰退してなければ・・・

Windowsだけでリポジトリを使う、あるいはLinuxだけでリポジトリを使うなら、Mercurialという選択肢があり、複雑怪奇なGitを使わなくても・・・と思いますが、現実はそう限定できないことが多いのです。
また、「ファイル名に日本語使うのがよくない」という意見もありますが、コンピューター側の制約に人間が不便な思いをして合わせるのは本末転倒と思うのでファイル名から日本語撲滅運動には加わりません。

ところで、Windows OSの標準ファイルシステムであるNTFSでは、ファイルパス文字列をユニコード(UTF-16LE)で格納しているのですが、エクスプローラーやほかのファイルを扱うアプリケーションがNTFS上のユニコードファイル名をCP932(Microsoft拡張Shift JIS)に変換してしまうので、少々複雑で込み入った状況があるようです。

さて、前置きが長くなってしまいましたが、今回は日本語ファイル名の対応の件ではなく、テキストファイルの改行コードの話が主題です。これも、Windows OSとLinuxUnix系)OSとが同じリポジトリを使用するときの問題です。ソースコードや設定ファイルなどのテキストファイルは行単位で構成されますが、行の終わりを示す文字(改行コード)がWindows OSではCR+LFの2文字、LinuxUnix系)OSではLFの1文字となっています。テキストファイルを扱うツール(例えばコンパイラ、エディタ、など)がどちらの改行コードでも正しく捌くことができればいいのですが、片方の改行コードしか扱うことができない場合、もう片方の改行コードが含まれたテキストファイルを正しく扱えず困ったことが生じます。また、1つのファイルの中で改行コードが異なる行が混在するというケースもあります。Unixのソフトウェア開発においては、本来改行コードにCR+LFが入ることはないと思ってましたが、開発者の中にはソースコードWindows OS上へコピーしてファイルを編集し、それを再度Unix上へコピーしてリポジトリに登録する人が少なからずおりました。そのような場合、Windows OS上で編集する際にCR+LFが混入してしまうことがあります。

これまでは、

Gitでは、改行コードを環境に応じて揃える機能が提供されており、リポジトリ内部では改行をコードをLFに揃えて、Windows OS上で作業ディレクトリにファイルを置くときはCR+LFコードとし、LinuxUnix)OS上で作業ディレクトリにファイルを置くときはLFコードとする、ということができます。

                                      +-- Windows OS ---+
                                      |  +-----------+  |
+-- リポジトリ --+          +---------+->|改行 CR+LF |  |
|  +----------+  |          |         |  +-----------+  |
|  |改行 LF   |<-+----------+         +-----------------+
|  +----------+  |          |          
+----------------+          |         +-- Linux OS -----+
                            |         |  +-----------+  |
                            +---------+->|改行 LF    |  |
                                      |  +-----------+  |
                                      +-----------------+

テキストファイルの改行コードを揃えるには、次の2つの方法があります。

  1. 各使用者のgitツールの設定で、core.autocrlfを指定
  2. リポジトリに属性設定(.gitattributes)を作成し、改行コードの扱いを指定

前者は、リポジトリにアクセスする全ての環境で同じ設定をしなければリポジトリの改行コードがそろわなくなります。
後者は、リポジトリにアクセスする環境での設定に関わらず、同じ方法を適用することができます。

core.autocrlfを指定する方法は、大抵のGit入門記事やブログで紹介されており、またGit for Windowsではインストール時にcore.autocrlfの設定値を選択するので内容を把握していました。そこで、最初はこの方法で改行コードを揃えようとしました。しかし、設定漏れがあれば改行コードが揃わなくなってしまい、定期的にリポジトリの中のテキストファイルの改行コードを検査する必要があります。

.gitattributesに指定する方法は、Gitの改行問題をこの1、2週間いろいろ調べまわった中で見かけたもので、これならリポジトリに設定ファイルを置くだけでリポジトリ利用者の設定を一括して制御できそうです。

さて、ここで気になるのが、バイナリファイルをリポジトリに入れたときに、テキストファイルとして扱われてファイル中のデータが変換されてしまうことがないか?です。バイナリファイルのデータの中で0x0aが0x0d 0x0aに変換されてしまったり、その逆に変換されてしまうことがあるのではということです。

単純なバイナリデータを2,3パターン作って試してみた限りでは、バイナリが変換されてしまうことはなかったですが、おそらく誤認されるパターンはありえます。.gitattributesにはバイナリとして扱うファイル名のパターンを指定できるので、それを併用するのが安全なのかと思います。

調査内容などは次のWikiに記述しています。.gitattributesはこれから試してみる予定です。

Gitリポジトリ管理 - ソフトウェアエンジニアリング - Torutk