Unity のための Git:何をコミットし、何を無視するか
Unity のプロジェクトを壊さずに Git を使うには?
Assets/、ProjectSettings/、そしてすべての .meta をコミットし、Library/、Temp/、obj/、Build/、Logs/ は無視します。誰かが clone する前に Version Control を Visible Meta Files、Asset Serialization を Force Text にし、大きなバイナリは最初から Git LFS に入れ、作業を prefab に分けて二人が同じシーンをマージせずに済むようにします。
Git は Unity と問題なく使えます。うまくいかない原因は、Unity のプロジェクトに三種類のファイルが混ざっていて — 自分の作ったもの、Unity がそれについて書き出すもの、Unity が一から作り直せるもの — Git にはその区別がつかないことです。間違った組をコミットすれば、リポジトリは pull のたびに衝突するギガ単位のゴミに変わります。最初に一度この三つを仕分けてしまえば、あとは普通の Git です。
三種類のファイル
自分の作ったもの:Assets/ の下にあるすべて — シーン、スクリプト、prefab、モデル、texture。リポジトリはこれのためにあります。
Unity がそれについて書き出すもの:ProjectSettings/、Packages/manifest.json、そして asset 一つにつき一つの .meta。軽く、そして必ずコミットしなければなりません。
Unity が自分で作り直すもの:Library/、Temp/、Logs/、obj/、Build/。ギガ単位で、マシンごとに違い、他人にとっては何の価値もありません。決してコミットしないこと。
まずプロジェクトを設定する
- 1
を開き、Version Control mode を Visible Meta Files に、Asset Serialization mode を Force Text にします。
- 2
Force Text はシーンと prefab をバイナリではなく YAML で書き出します。バイナリのシーンは Git にとって読めない塊でしかなく、何が変わったかも見えず、二人の作業を統合することも永久にできません。
- 3
この二つの設定は、誰かがプロジェクトを clone する前にコミットしてください。後から変えると、すべてのシーンファイルが一つの巨大なコミットで書き換わります。
.gitignore
これはリポジトリのルート、Assets フォルダと同じ階層に置きます。末尾のスラッシュには意味があります — フォルダを指すので、たまたま Temp という名前のファイルは今も追跡されます。
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
[Uu]serSettings/
[Mm]emoryCaptures/
# Editor and OS noise
.vs/
.idea/
.DS_Store
*.csproj
*.sln
*.user
# Build outputs
*.apk
*.aab
*.unitypackage
# Crash reports
sysinfo.txtLibrary をすでにコミットしてしまったら
git rm -r --cached Library Temp obj Build
git commit -m "Stop tracking generated folders"--cached はディスクから消さずに Git の追跡だけを外します。履歴には残るのでリポジトリは誰かが書き換えるまで大きいままです。まだ若いプロジェクトなら、git filter-repo を覚えるよりリポジトリを作り直すほうが速いことがほとんどです。
大きなファイル:texture、モデル、音声
Git はバイナリファイルが変わるたびに、まるごと新しいコピーを保存します。40 MB のモデルを十回書き出し直せば、リポジトリは 400 MB を永久に抱えます。Git LFS は代わりにポインタだけを保存し、実体は別の場所に置きます。
git lfs install
git lfs track "*.psd" "*.fbx" "*.blend" "*.wav" "*.mp3" "*.mp4"
git add .gitattributes二人、一つのシーン
ここは Git が代わりに解決してくれない部分です。シーンファイルは中の全オブジェクトを記述した一つの YAML 文書なので、同じシーンの別の隅をいじっている二人でも、触っているファイルは同じ。そして Git は、正しく行う術のないマージを差し出してきます。
作業を prefab に分けます。一人は敵の prefab、もう一人は UI の prefab を持ち、シーンにはインスタンスだけを置く。prefab が二つなら二つのファイルであり、二つのファイルは衝突しません。
大きなレベルには additive なシーンを使います。エリアごとに一つのシーンを用意し、実行時にまとめて読み込む。各自が自分のファイルを開くことになります。
誰がシーンを開いているかを声に出して言うこと。二、三人のチームなら、どんなツールより速く確実です。
それでも .unity ファイルで衝突が起きたら、片側をまるごと採用し、もう片側の作業は手でやり直してください。手で統合した YAML のシーンは壊れたファイルとして開くことが十分に多く、試す価値がありません。