BLOGakisuteが主に技術的なネタを書き溜めるブログです。投稿を表示しています。投稿を表示しています。3.5でバージョン管理をするおよそコンピュータを使った仕事に該当するものでしたら何でも、複数の人物が同時に作業するための何らかの仕組みが必要になるのは、コンピュータを使った仕事に関わっている人でしたら皆ご存知かと思います。開発業務といえばgitやhgといったバージョン管理システムの出番になります。プロジェクトでのバージョン管理について一ヶ月間ほどやってみた結果をご紹介したいと思います。3.4以前の場合そんな暗黒時代のことは忘れましょう。バージョン管理システムを使う以外に、好きなバージョン管理システムを使ってUnityのプロジェクトをバージョン管理することができるようになりました。これを使わない手はありません。公式のガイドを見てみましょう。http://unity3d.com/support/documentation/Manual/ExternalVersionControlSystemSupport.htmlこれによると、以下の手順を踏むのが良いようです。これで外部のバージョン管理システムが導入できるようになります。このチェックを入れると、Libraryディレクトリが重要なメタデータを管理するディレクトリではなくただのキャッシュディレクトリになり、バージョン管理をしなくてよくなる。新たにAssetsディレクトリ以下のすべてのファイルとディレクトリについて.metaファイルが生成される。新たにProjectSettingsディレクトリが生成される。この手順はどちらかと言うとおまけです。これを実行すると、ほとんどのAssetファイルがバイナリではなくテキスト形式で保存されるようになり、diffやmergeが行えるだけではなく差分だけをコミットするようになるためバージョン管理システムが扱うデータ量が減ります。プロジェクト配下のAssetsディレクトリとProjectSettingsディレクトリをバージョン管理システム配下に追加する。それ以外のファイルは追加しなくて良い。簡単そうですね!ということで早速やってみました。・・・ところがぎっちょん、実際にやってみると出るわ出るわ問題の山。■.metaファイルがどこからともなく勝手に生成されるこれが最大の問題です。外部バージョン管理をするためにUnityが.metaという名前のメタファイルをテキスト形式で生成するのですが、コイツがトラブルを起こしまくります。ファイル削除時に.metaを消すのを忘れて、同じ名前のファイルをあとから作成しようとして.metaがぶつかりトラブルになるファイルも.metaもバージョン管理下から確かに消したはずなのに、なぜか.metaファイルだけが勝手に復活しているブランチを移動すると急に.metaファイルが湧いてきて、ブランチのマージ時に衝突する主要な原因はUnityが空のディレクトリから.metaファイルを生成しているためです。以下のようなケースで、中身が空のディレクトリというのは容易に生成されてしまいます。gitの場合gitはディレクトリをバージョン管理対象に含めないため厄介なことになります。pull時にmerge/rebaseが実行され、その際に空になったディレクトリは削除されるのですが、merge/rebaseの最中に衝突が発生したりすると問題が大きくなります。merge中に裏でUnityが動いていると空ディレクトリの.metaがその場で生成されて、考えるだけでも恐ろしいことになったりします。通常はこれで問題ないのですが、merge/rebase時に衝突が発生していて、裏でUnityが動いていたりすると酷いことになるみたいです。update時に空になったディレクトリをきちんと削除してくれます。directoryの中身を指定されたリビジョンの状態にするから、という認識です。gitと違いpullやupdate時にmerge/rebaseを実行しないためトラブルになりづらいのか?などと考えてますが実際に苦労したわけではないのでよくわかりません。gitよりはトラブルになりづらいとは思います。1および3にupdateすると、きちんとFolderやOtherFolderが削除されてくれます。svnの場合ディレクトリもバージョン管理の対象にするので問題ありません。r2のような削除の仕方をするとFolderが残ってしまうためFolder.metaが生成されてしまうのですが、普通はディレクトリを消したときはr4のような削除の仕方になるので問題がないはずです。中身が事実上空なディレクトリ(すでに使われていない.metaしか入っていないディレクトリなど)が亡霊みたいにさまよっていて延々と自身の.metaを書き出し続けたり、善意で予め作っておいた空ディレクトリが.metaを吐き出していることを知らずコミットされては削除されを繰り返していたり、二人が同時にディレクトリを削除しようとして片方のコミットが衝突して結果が壊れてしまったりなど、枚挙に暇がありません。元ファイルを移動したり削除した際に.metaを消さなくてはいけないというだけでも極めて面倒で、相当なトラブルになりました。そもそもがUnityを使っているプロジェクトのメンバーが全員バージョン管理システムに慣れていないため、とりあえずバージョン管理システムのGUIツールがいうがままに変更を全部コミットするだけという具合の運用に。.metaだけが延々と残って衝突が繰り返されるという悲惨な状況が発生してしまうこととなりました。これはUnityのせいではなくメンバーがバージョン管理の考え方を正しく理解していないのが問題なのでツールは何を使っても発生しうるのですが、.metaがなければここまで問題は拡大しなかったと思います。ignoreしてしまいたいぐらいなのですが、この.metaにファイルごとのメタ情報が全て詰まっているため、当然ignoreするとプロジェクトがブッ壊れます。■.unityファイルがマージできない.unityファイル自体はテキスト形式にできるのですが、中で使われているAssetのIDがちょっと触れただけでものすごい勢いで変化したり、他人の環境では別の値になったりするため、殆どの場合マージできません。iOSプロジェクトのxcodeprojファイルみたいな感じです。こればかりはマージを諦めるしかありません。■まとめ最初はgitを使って管理をしていたのですが、上記に挙げたような問題が多発しまくって回らなくなってしまいました。Serverを購入して試してみることになりました。Serverならば.metaを使わないでバージョン管理できるので問題を根本的に解決できそうです。逆に言えば.metaに気をつければそれ以外の箇所ではgitでもあまり問題になりませんでした。バイナリを大量に扱うため重いのではないかと懸念されていましたが、github経由ででも問題なくpush/pull出来る程度の重さにしかならなかったです。Serverなしでも十分やっていけるのではないかと思いました。個人的にUnityでバージョン管理をする際におすすめする外部バージョン管理システムはsvn、可能であればPerforceです。git/hgのようにブランチを主体とするバージョン管理システムはブランチを切り替えた瞬間に.metaに殺されるケースが多々あるため、ブランチの使用そのものが非推奨となり、力が発揮できません。mergeについてもバイナリファイルやmergeできないテキスト形式のファイルが多くて結局意味がない気がします。しても分散VCSを使いたい!というならhgをお勧めします。-Cすることで対応できるかなと。bazaarはわからないのでノーコメント。gitはpull時の衝突の最中に裏でUnityが動いていて大爆発するケースがあったのでやめておいたほうが良いです。hgなら少なくともpull/update時に爆発することはないはずですからね。Serverを試してみて、使用感を書いてみようかと思います。されることがあります。送りたいことがあります。こんなときにどうすればよいかをまとめてみました。このボタンをぽちっとな。