Unityのプロジェクトで後からGit LFSを適用して過去を修正する方法

目次

概要

Unityのプロジェクトで後からGit LFSを利用することにしました。その際に、Git LFS管理のファイルを過去に遡って適用する方法を説明します。

環境

  • Unity 2021.3.20f1
  • Git 2.39.1
  • Git LFS 3.3.0

やりたいこと

Unityのプロジェクトでは、たくさんのバイナリファイルを扱います。Gitは、テキストファイルであれば、差分を圧縮して保存することからリポジトリのサイズを小さくしつつバージョン管理できますが、バイナリファイルでは、そうはいきません。

そのようなときのために、Git LFSがあります。Git LFSは、指定したバイナリファイルなどを効率的に扱うためのツールです。通常であれば、フェッチしたブランチに含まれる全ての差分をダウンロードするのですが、Git LFSを使えば、基本的に最新のもののみをダウンロードするため(指定すれば過去のものもダウンロード可能)、リポジトリの操作を高速に行うことができます。

そこで、ローカルにクローンしたリポジトリのサイズを抑えたり、バイナリファイルの管理を効率化するためにGit LFSを導入することにしました。

過去の履歴を遡って適用

Unityのプロジェクトで、Git LFS管理するものを.gitattributesに記述します。これは、インターネットを検索して見つけたものを利用しました。

*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text
*.tiff filter=lfs diff=lfs merge=lfs -text
*.iff filter=lfs diff=lfs merge=lfs -text
*.pict filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.aiff filter=lfs diff=lfs merge=lfs -text
*.mod filter=lfs diff=lfs merge=lfs -text
*.it filter=lfs diff=lfs merge=lfs -text
*.s3m filter=lfs diff=lfs merge=lfs -text
*.xm filter=lfs diff=lfs merge=lfs -text
*.aif filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.avi filter=lfs diff=lfs merge=lfs -text
*.mpg filter=lfs diff=lfs merge=lfs -text
*.mpeg filter=lfs diff=lfs merge=lfs -text
*.asf filter=lfs diff=lfs merge=lfs -text
*.FBX filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.dae filter=lfs diff=lfs merge=lfs -text
*.3ds filter=lfs diff=lfs merge=lfs -text
*.dxf filter=lfs diff=lfs merge=lfs -text
*.max filter=lfs diff=lfs merge=lfs -text
*.ma filter=lfs diff=lfs merge=lfs -text
*.mb filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.otf filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text
*.rar filter=lfs diff=lfs merge=lfs -text
*.tar filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.lzh filter=lfs diff=lfs merge=lfs -text
*.7z filter=lfs diff=lfs merge=lfs -text
*.spm filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.unitypackage filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
LightingData.asset filter=lfs diff=lfs merge=lfs -text

しかし、これを設定しただけでは不十分です。これからコミットするファイルについては、指定したファイルがGit LFSの対象になりますが、既にコミットされているものは、そのままです。

そこで、Git LFSで用意されているmigrateコマンドを利用して、コミットの履歴をさかのぼり、Git LFSの対象となるようにします。

この作業を行う際は、失敗やおかしな結果となることもあるため、一度リポジトリのディレクトリをバックアップしておくことをおすすめします。

次のコマンドを実行します。

git lfs migrate import --include="*.jpg,*.jpeg,*.png,*.gif,*.psd,*.ai,*.bmp,*.tiff,*.iff,*.pict,*.mp3,*.wav,*.ogg,*.aiff,*.mod,*.it,*.s3m,*.xm,*.aif,*.mp4,*.mov,*.avi,*.mpg,*.mpeg,*.asf,*.FBX,*.fbx,*.blend,*.obj,*.dae,*.3ds,*.dxf,*.max,*.ma,*.mb,*.ttf,*.otf,*.a,*.so,*.dll,*.exr,*.tga,*.pdf,*.zip,*.rns,*.reason,*.lxo,*.rar,*.tar,*.gz,*.lzh,*.7z,*.spm,*.tif,*.tiff,*.unitypackage,*.apk,LightingData.asset" --everything

--includeオプションに指定しているのは、Git LFSの対象にするファイルの拡張子です。上記の.gitattributesの内容を元にしています。

コマンドで指定したファイル名について、.gitattibutesに追記されます。既に設定されている内容を改めて書いているため、削除します。

最後に、リモートのリポジトリに変更を反映させます。過去のコミット履歴も変更しているため、forceオプションを利用してプッシュを行います。

git push origin main -f

うまくいけば、これで終わりです。

さいごに

git lfs migrateで指定する拡張子の一覧を作成するのが面倒でした。

Gitは、どうしてもバイナリファイルを扱うのが不得手ですので、大量のバイナリファイルを扱うと分かっているのであれば、最初からGit LFSを導入しておくことをおすすめします。