Git LFSで様々なストレージサービスを使えるlfs-dal
Gitで大きなファイルを管理するには
今やコードのバージョン管理に必須なGitですが、大きなサイズのファイルを管理したくなることがしばしばあります。例えば、ゲーム開発をしていたらゲームのアセット、機械学習レポジトリでは学習済みの重みデータなどです。Gitの通常のファイル管理では大きなファイルを扱えません。そこで様々な方法が考案されてきました。
- git-lfs
- GitHubなど主要なホスティングサイトでサポート
- Gitと同じ操作感で使用できる
- git-annex
- クラウドストレージを含む様々なバックエンドを利用可能
- 多機能であるがゆえ複雑
- (番外編)Gitをやめて他の大規模向け管理ツールを使う
いくつか選択肢がありますが、おそらくGitで大きなファイル管理ではLFSが一番使われているでしょう。
Git LFSの問題
Git LFSも万能ではありません。
- clean/smudgeフィルターでローカルキャッシュ
.git/lfs
からファイル内容をコピーしてくる実装なので、ローカルストレージを2倍消費する(Copy-On-Writeなファイルシステムでgit-lfs-dedupが使用可能な場合を除く)。 - (標準では)ストレージバックエンドの選択肢がありません。例えばGitHubでは、GitHubが用意した無料枠1GBのストレージしか使用できませんし、サーバーのリージョンも選べません。また、要らなくなったファイルを削除することは困難です(レポジトリごと消せば可能)。
前者は、ちょっとお金を出してローカルストレージ容量を足したり、BtrfsなどCOWなファイルシステムを使えば解決できます。一方で後者は、それほど簡単ではありません。
Custom Transfer Agent
実はGit LFSはCustom Transfer Agentを用意すればファイルの転送をカスタマイズできる機能があります。前のセクションで「標準では」とかっこ書きを入れたのはそのためです。この機能を使えば、Git LFSの操作感をそのままにストレージバックエンドを任意のものに置き換えることができます。
ということで、様々なサービスにファイルを保存できるlfs-dalを作りました。
lfs-dalの特徴
既存のCustom Transfer Agentもありますが自作したモチベーションは以下です。
- レポジトリに格納して他の開発者と共有したい情報(エンドポイント・バケット名など)と秘密の情報(認証関連)を分けたい
- 失敗時に詳細なログを確認したい
- インストールを簡単にしたい
(1)lfs-dalでは、設定を読むときに.lfsdalconfig
と.git/config
も読みます。共有して問題ない情報は.lfsdalconfig
に書いてレポジトリにコミット、それ以外は開発者のローカル環境に保存という運用ができます。
(2)Custom Transfer AgentはGit LFS経由で起動されて標準入出力がGit LFSに握られているので、他の場所にログを出す必要があります。lfs-dalは必要に応じてファイルにログ出力します。特にクラウドストレージへの接続は失敗するポイントがいくつもあるので、原因の特定手段が必要です。
(3)OpenDALにより外部依存なしで様々なストレージサービスにアクセスできるので、lfs-dalはバイナリ1つを適当な場所に配置するだけで動作します。
他の選択肢
- rudolfs
- こちらはCustom Transfer Agentではなく、LFSサーバーの実装になります。Custom Transfer Agentと違ってあらかじめサーバーを起動しておく必要があります。いい点としては、サーバーと一緒に認証情報を閉じ込めておけるので、各開発者に認証情報を渡さず安全なイントラネットにサーバーを立てて複数人がアクセスする運用ではこちらのほうがマッチするでしょう。
- lfsrclone
- Pythonで実装され、rcloneを転送に使うCustom Transfer Agentです。Python・rcloneのインストールが必要になります。
- lfs-os
- Rust実装のCustom Transfer Agentでlfs-dalに一番近いです。実装の参考にしました。
ロゴの出典:Git LFS logo、OpenDAL logo