2011年1月30日日曜日

Subversion導入時の注意点(改行コード、実行権限)その1

Subversion導入後にファイルの改行コードおよび実行権限で色々問題が発生したので、その時の対応をまとめたいと思います。

開発者はLinux、デザイナーさんはMac OS、HTMLのコーダーはWindowsみたいな状況って普通にあることだと思うんですが、このようなOSが混在する状況で、ちょっと困った問題が発生しました。

皆がそれぞれの環境で作成したファイルを、Subversionにコミットしていたんですが、ある日、Linux上でCheckoutしたPerlスクリプトファイルを実行しようとしたところ、次のようなエラーが発生しました。

$ ./test.pl
-bash: ./test.pl: Permission denied


あれれ、実行できない。
lsで確認すると。

$ ls -la test.pl
-rw-rw-r-- 1 yt yt 172 Jan 28 18:08 test.pl


おや?実行権限が無い。。。。
まぁいっか、chmodで実行権限を付与して実行してみよう。

$ chmod 755 test.pl
$ ./test.pl
-bash: ./test.pl: /usr/bin/perl^M: bad interpreter: No such file or directory


今度は意味不明なエラーが発生。
そこで、このファイルをvimエディタで開いてみると、ステータスバーに以下の表示。

"test.pl" [noeol][dos] 9L, 172C

どうやらファイルの改行コードがWindows(DOS)形式になっていたことが原因で、エラーが発生していたようです。

そこで、こちらを参考にして、vimのコマンド set ff=unix を使って、改行コードをUNIX形式に変換しました。
すると、エラーが発生しなくなりました。

なぜ、こんなことになったのか?
ということで調べたところ、このファイルは元々Windows上で作成し、WindowsのSubversionクライアントのTortoiseSVN経由でリポジトリにaddされたことがわかりました。

そもそもWindowsというOSにはUNIX系OSでいうところの実行ビットという概念が存在しないですし、改行コードも異なるので、なるほどこんな問題が発生しても不思議ではありません。

この問題をどうにか解決できないのかを調べていたところ、Subversionの日本語マニュアルにたどり着きました。
それによれば、Subversionはファイルやディレクトリに対して属性というメタデータを設定することができて、そのメタデータ自体もバージョン管理されるということでした。
さらに属性には、Subversion自身が使用している特殊な属性があり、それを使うとこの問題を解決できることがわかりました。
具体的には、svn:executable と svn:eol-style という属性名なんですが、それぞれの意味は、

svn:executable
ファイルに対してこの属性名が設定されていると、OSが対応していれば実行ビットが有効になる。
属性値は無い。

svn:eol-style=native
Checkoutする際に、ファイルに含まれる改行コードをCheckout先のOSに応じて変換する。
つまり、Windowsの場合は CRLF に変換され、UNIX系OSの場合は LF に変換されます。
逆にaddやcommitなどのコマンドでリポジトリにファイルを格納するときには、 オペレーティングシステムにはよらず、正規化された改行コード(LF)に変換されてリポジトリに格納されます。


だいたい上記のような意味だと私は解釈しました。
早速テストしてみました。実行結果はこんな感じです。

$ ls -la test.pl
-rw-rw-r-- 1 yt yt 23 Jan 28 18:59 test.pl
$ svn ps svn:executable '' test.pl ←svn:executableの設定
property 'svn:executable' set on 'test.pl'
$ ls -la test.pl
-rwxrwxr-x 1 yt yt 23 Jan 28 18:59 test.pl ←実行権限が付与された!
$ ./test.pl
-bash: ./test.pl: /bin/bash^M: bad interpreter: No such file or directory
$ svn ps svn:eol-style 'native' test.pl ←svn:eol-style=nativeの設定
property 'svn:eol-style' set on 'test.pl'
$ ./test.pl ←svn:eol-style=nativeを設定しただけではEOLの変換は行われないのでエラーになる
-bash: ./test.pl: /bin/bash^M: bad interpreter: No such file or directory
$ svn commit ←commitの段階でファイルのEOLがLFで正規化されてリポジトリに保存される
Sending test.pl
Transmitting file data .
Committed revision 31.
$ ./test.pl ←エラーが無くなり、実行可能になった!!
hello


という訳で、OSが混在する環境でSubversionを使用している場合は、
・実行ビットが必要なファイルには、svn:executable 属性を設定。
・テキストファイルには、svn:eol-style 属性に native という値を設定
しておけばよいという結論になりました。

次回のエントリでは、そもそもそういった問題が発生しないためには何をすればよかったのか?について書きたいと思います。

参考にしたURL:
http://advweb.seesaa.net/article/3074705.html
http://demo.zeera.jp/files/cubo/cubo-demo/document/01.Cubo-Manual/html/subversion/svn.advanced.props.html
http://cesare.seesaa.net/article/44146340.html

0 件のコメント:

コメントを投稿