
Epic Games のバージョン管理 Lore を現場目線で Perforce / SVN / Git と比較した
はじめに
Epic Games が 2026 年 6 月にオープンソースのバージョン管理システム Lore を公開しました。ゲームやエンタメ制作のような、コードと大容量バイナリが混在するプロジェクトを主な対象としています。本記事では、Lore を実際にローカルへインストールし、Perforce、SVN、Git、Git LFS と比較します。
現場の悩みは、ストレージ効率そのものよりも、排他ロックの運用、サーバー往復の依存、ライセンスコスト、そしてバイナリの衝突にあります。本記事では、これらの悩みに Lore がどう応えるかを、実際の操作の結果で確かめました。Lore はバイナリ対応、オフライン耐性、重複排除という長所を持ちます。一方で、バイナリの同時編集による作業の消失を防ぐ強制ロックを、現時点 (2026 年 7 月時点) では備えていません。 ここが Perforce との違いです。
Lore とは
Lore とは、Epic Games が 2026 年 6 月に公開したオープンソースのバージョン管理システムです。コードと大容量バイナリが混在するプロジェクト、特にゲームやエンタメ制作を主な対象としています。
検証環境
- OS: macOS 26.5.1 (Apple Silicon, arm64)
- Lore / loreserver: 0.8.4
- Git: 2.54.0
- Git LFS: 3.7.1
- Perforce (p4 / p4d): 2025.2 (macOS ARM64 ネイティブ)
- SVN: 1.14.5
各ツールは同一マシン、同一データ、同一操作で検証しました。ストレージ比較では、格納方式の違いが挙動に出るため、各ツールのファイルタイプや設定を実運用に即した標準的なものに揃えています。Perforce はデフォルトの binary タイプ (gzip 圧縮の full copy) を使いました。検証データは、シードを固定して生成した合成バイナリで、基準サイズは 200MiB としました。このデータはランダムに近く、ほとんど圧縮されないようにしています。
対象読者
- Perforce を使っていて、シート課金やサーバー往復への依存に悩んでいる方
- ゲーム開発やエンタメ制作に携わり、コードと大容量バイナリの混在を扱う方
- 大容量バイナリを Git や Git LFS で扱っていて、リポジトリの肥大化や帯域コストに悩んでいる方
- Lore が Perforce や SVN、Git と比べて実際どう振る舞うのかを知りたい方
参考
検証 1: 1 バイト変更時の増分
最初に、大容量バイナリを少しだけ変更したとき、各ツールのリポジトリ側のストレージがどれだけ増えるかを測りました。
200MiB のバイナリを初版として登録した後、次の 3 通りの変更を加えた版を登録し、その増分を測定します。
- 末尾追記: 末尾に 4KiB 追記する。
- 先頭付近への挿入: 先頭近くに 4KiB 挿入し、以降のバイトオフセットをずらす。
- 中間の 1 バイト変更: 中央の 1 バイトだけを書き換える。
測定結果は次の通りです。値は変更版を登録したときのストレージ増分です。
| 変更の種類 | Git | Git LFS | SVN | Lore | Perforce |
|---|---|---|---|---|---|
| 末尾に 4KiB 追記 | 約 200MiB | 約 200MiB | 約 43KiB | 約 191KiB | 約 200MiB |
| 先頭付近に 4KiB 挿入 | 約 200MiB | 約 200MiB | 約 8.1MiB | 約 207KiB | 約 200MiB |
| 中間の 1 バイト変更 | 約 200MiB | 約 200MiB | 約 39KiB | 約 163KiB | 約 200MiB |
Git、Git LFS、Perforce は、変更の大小や種類に関係なく、毎回フルサイズ 1 個分を丸ごと追加しました。1 バイトしか変えていなくても約 200MiB 増えます。これらはバイナリのバージョン間で差分を取らないためです。Git はバイナリをデルタ圧縮せず、Git LFS はオブジェクトを丸ごと保存し、Perforce のバイナリはリビジョンごとに full copy を保持します。
SVN は svndiff によるバイト差分を保存するため (どのリビジョンを基準に差分を取るかは skip-delta という仕組みで決めます)、末尾追記と中間の 1 バイト変更では数十 KiB に収まりました。ただし先頭付近への挿入では約 8.1MiB に増えます。挿入で以降のバイトが全部ずれると、バイト差分では効率が落ちるためです。
Lore は FastCDC という内容依存のチャンク分割を使い、どの変更でも約 160 から 210KiB に収まりました。特に挿入への強さが際立ちます。挿入でオフセットがずれても、内容依存で境界を決めるため、変更の影響を受けたチャンクだけを追加すれば済みます。この挿入のケースでは、Lore は SVN を大きく下回りました。
この結果は、ストレージコストとリポジトリの肥大化に直結します。Git や Git LFS で大容量アセットを日常的に更新すると、変更のたびにフルサイズが履歴に積み上がります。1 週間に何度もアセットを更新すれば、リポジトリはあっという間に膨らみます。これが Git LFS のストレージと帯域のコストにつながります。
Perforce も full copy ですが、Perforce はサーバー運用が前提で、部分同期などで実運用に耐える設計になっています。Lore は、Perforce のようなバイナリ対応と、SVN や Git を上回る差分効率を、オープンソースで両立しようとしている点が特徴です。
検証 2: Lore はいつコンテンツをサーバーへ送るのか
検証 1 の測定中に、ある挙動に気がつきました。Lore の push の表示です。200MiB のファイルを含む初回の push で、CLI は次のように表示しました。
Pushing 1 fragment(s)
Pushed 1 fragment(s), 124.00 bytes
124 バイトしか送っていないと読めます。しかし push 後、サーバー側のストレージは約 200MiB に増えていました。表示と実体が食い違っています。
ソースコードとサーバーログを精査し、実機でも検証した結果、原因が判明しました。 Lore はデフォルトで、サーバーが到達可能なとき、コンテンツを push ではなく commit の時点でサーバーへ先行アップロードします。 push はブランチポインタの更新と残りのメタデータだけを送ります。
実機での測定は次の通りです。サーバーを起動した状態で、200MiB のファイルについて、各操作の後にサーバーのストレージを測りました。
| 操作 | デフォルトの commit | --offline を付けた commit |
|---|---|---|
| stage の後 | 約 930 バイト | 約 931 バイト |
| commit の後 | 約 200MiB | 約 931 バイト |
| push の後 | +約 340 バイト | 約 200MiB |
デフォルトでは commit の直後にストレージが約 200MiB へ急増し、push ではほとんど増えません。--offline を付けると commit ではアップロードされず、push のときにまとめて送られます。
この設計には、現場にとって良い面と注意点の両方があります。
良い面として、オンラインで作業していれば push が速くなります。コンテンツは commit の時点で送信済みのため、レビュー直前やブランチ公開の push でまとまった待ちが発生しません。転送のコストが commit ごとに分散して支払われます。ただし、commit 時にサーバーへ送られるのはコンテンツ (フラグメント) だけで、そのコンテンツがどのブランチから参照されるのは push の後です。したがって、push 前の commit 内容はまだ他者から復元できる状態ではなく、これを完全なバックアップと考えるのは早計です。
注意点として、サーバーが到達可能なとき、デフォルトの commit は先行アップロードの完了を待ちます。Git の commit が完全にローカルで一瞬なのに対し、Lore でオンラインのまま大容量バイナリを commit すると、その本体のアップロードのあいだ commit が待たされます。低速な回線やリモート環境では commit が重くなります。commit を軽くしたいときや、明示的にオフラインで作業したいときは、次の検証 4 で示す --offline を付けます。
Git ユーザーにとっては、違和感があるかもしれません。オンライン時の Lore の commit は、実質として commit とコンテンツの先行アップロードを兼ねており、ブランチの公開だけが push で行われるような動作をするからです。
検証 3: 排他ロックについて
ここが Perforce ユーザーにとって最も重要な検証です。マージできないバイナリを 2 人が同時に編集すると、片方の作業が失われます。これを防ぐのが排他ロックです。各ツールで、2 つの作業コピー (userA, userB) を用意し、userA がロックした状態で userB が編集や更新をできるか確かめました。
Lore のロックは通知するだけで止めない
Lore には lore lock acquire があります。実機で検証すると、次のような挙動となりました。
userA がロックを取得すると、そのロックは userB の作業コピーからも見えます。userB が同じファイルにロックを取ろうとすると、二重取得は拒否されます。ここまでは Perforce に近く見えます。
しかし、userB は userA がロック中のファイルを編集し、commit し、push できてしまいました。上書きに成功し、警告すら出ません。
############ userB: ロック中のファイルを編集して push
-- commit --
Commit succeeded
-- push --
Pushed revision 2 -> ... to branch main
Lore のロックは勧告的です。誰がロック中かを共有し、二重ロックは防ぎますが、ロック非保持者による編集や push を止めません。これは公式 FAQ の記述とも一致します。強制ロックはロードマップ上の将来課題です。
Perforce の排他ロックは編集の開始時点で止める
Perforce では、ファイルタイプ +l (exclusive open) を使うと、userA が編集オープン中は userB は編集オープンすらできません。
############ userB: 同じファイルを p4 edit
//depot/model.bin - can't edit exclusive file already opened for edit
... //depot/model.bin - also opened by tester_a@wsA
userB は 1 ファイルも開けませんでした。サーバーが強制するため、同時編集そのものが成立しません。
SVN も commit の段階で止める
SVN では、svn:needs-lock を設定したファイルは作業コピーで読み取り専用になり、ロックを取れという合図になります。この読み取り専用は Git LFS と同じく chmod +w で外せる勧告的な仕組みです。ただし SVN が Git LFS と違うのは、その先です。userA がロックした後、userB のロック取得は拒否され、userB が読み取り専用を外して編集し commit しようとしても、サーバーが拒否しました。Git LFS の push ブロックがクライアント設定 (locksverify) 次第なのに対し、SVN はロック非保持者の commit をサーバー側で拒否します。
svn: E160039: User 'userB' does not own lock on path '/model.bin' (currently locked by 'userA')
Git LFS の強制はクライアント設定に依存する
Git LFS には git lfs lock があります。lfs-test-server を相手に検証したところ、次の 3 段階の挙動でした。まず --lockable を設定すると、ロック非保持者の作業コピーではファイルが読み取り専用になります。次に、二重ロックは拒否されます。そして push の可否は、クライアント側の locksverify 設定に依存します。locksverify を true にすれば、ロック非保持者の push はブロックされます。設定しない場合は警告のみで push は通ります。
ただし、chmod +w で読み取り専用を外せますし、locksverify を false にすれば検証を無効化できます。サーバーが必ず強制する Perforce とは異なり、強制はクライアント設定と運用に依存します。
5 者のロック強制力
検証で判明した強制力の順位は次の通りです。
Perforce と SVN はサーバーが強制します。Git LFS は、--lockable による読み取り専用化と二重ロック拒否で抑止し、locksverify=true を設定すれば push もブロックできますが、その強制はクライアント設定に依存し、chmod +w や locksverify=false で回避できます。Lore は現状、二重ロックこそ防ぐものの、編集や push は止めない純粋な勧告です。
Perforce のゲーム開発現場は、排他ロックによってバイナリの同時編集を構造的に防ぎ、作業の消失を避けています。Lore の現状のロックは、この保護を提供しません。ロックを取っていても、他者に上書きされうる形になります。
検証 4: オフラインで作業できるか
Perforce の悩みの 1 つに、サーバー往復への依存があります。サーバーに接続できないと作業が止まります。Lore がここにどう応えるかを確かめました。
Lore では、サーバーを停止した状態でも、--offline を付けることで commit とブランチ作成ができました。その後サーバーを再起動すると、push で同期できました。
############ サーバー停止中
lore --offline commit "v2 offline edit" -> Commit succeeded
lore --offline branch create feature-offline -> Created branch
############ サーバー再起動後
lore push -> feature-offline を作成、フラグメントを送信
対照的に、中央集権モードの Perforce は、サーバーが停止しているとファイルを編集オープンすることすらできませんでした。
############ サーバー停止中
p4 edit note.txt -> TCP connect to localhost:1668 failed. connect: Connection refused
分散やリモートでの開発が一般的になる中で、オフライン耐性はチームの生産性に直結します。中央集権モードの Perforce の現場では、VPN が不安定なとき、サーバーのメンテナンス中、移動中などに作業が完全に止まります。Lore は中央集権の使い勝手を保ちながら、--offline でこの制約を外せます。移動中でも commit やブランチ作成を続け、接続が戻ったら push で同期できます。
ただし、検証 2 で見たように、Lore のデフォルトの commit はサーバーが到達可能なとき先行アップロードします。オフラインで軽く作業したいときは --offline を明示します。
検証 5: バイナリが衝突したらどうなるか
2 つのブランチが同じバイナリを別々に変更してマージすると、どうなるかを確かめました。Lore では、マージ時に 3-way の差分を計算し、バイナリの衝突を検出しました。
Merged files, 0 updated, 0 deleted, 0 merged, 1 conflicted
Files in conflict:
model.bin
解決は lore branch merge resolve mine または theirs で行います。すなわち、ファイルを丸ごと片側だけ選びます。実際に theirs を選ぶと、内容はマージ元のブランチの版になりました。
バイナリがマージできないという事実は、ゲーム開発の日常に重い意味を持ちます。2 人が同じアセットを別々に編集して衝突すると、どのツールでも片方の版を丸ごと捨てるしかありません。つまり片方の作業が失われます。だからこそ、衝突を事前に防ぐ排他ロックが決定的に重要になります。ここで検証 3 の結果が意味を持ってきます。Lore のロックは現状、勧告的で、ロック非保持者の上書きを止められません。つまり Lore では、ロックを取っていてもバイナリ衝突が起こりえて、その衝突は片側選択でしか解けず、誰かの作業が失われうるのです。Perforce の強制ロックは、この問題を解決するための仕組みです。
まとめ
Lore を Perforce、SVN、Git、Git LFS と実際に触り比べた結果をまとめます。
Lore の長所は明確でした。バイナリの小変更を FastCDC で効率よく差分格納し、特に挿入に強いです。中央集権型でありながら --offline でオフライン作業ができます。オンライン時は commit の時点でコンテンツを先行アップロードするため push が速くなります。そしてオープンソースでライセンスコストがありません。
一方で、現時点での最も気になるのは、強制ロックが未実装である点です。 Lore のロックは勧告的で、バイナリの同時編集による作業の消失を防げません。バイナリはどのツールでもマージできないため、この保護の有無はゲーム開発の現場で大きな差になります。Perforce の排他ロックに依存しているチームは、自分たちのワークフローに照らして評価する必要があります。
強制ロックは Lore のロードマップにあり、将来的には埋まりうるギャップです。バイナリ対応とオフライン耐性を両立し、かつオープンソースであるという方向性は、Git と Perforce のあいだで悩んできた現場にとって、注目に値する選択肢だと言えます。





