Git LFSのコスト爆発とUnrealアセットの競合を解決するLore VCS移行ガイド
TuBrief 편집팀
2026년 7월 14일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
プロジェクトが大きくなると、Git LFSは災害へと変貌します。ソースコードの数行の修正は一瞬ですが、ギガバイト単位のアートアセットが混ざり始めると、1回のコミットごとに砂時計が数十秒間回り続けます。巨大なファイルを丸ごとコピーして蓄積するLFSの鈍重な構造のせいで、リポジトリ容量はすぐにテラバイトを超え、帯域幅の利用料請求書には恐ろしい数字が刻まれます。
エピックゲームズがオープンソースとして公開したLoreは、バイナリファイルを最優先で扱います。ファイルをブロック単位に分割して重複を排除するFastCDC方式を採用しており、パッケージ容量と転送帯域幅を劇的に削減します。DevOpsの専門人材がいない小規模チームでも今すぐ適用できる、Loreの実務的な移行および最適化手法をまとめました。
既存のGitリポジトリに蓄積されたソースコードのコミット履歴をわざわざ捨てる必要はありません。軽量なコードはGitにそのまま残し、重いバイナリアセットだけをLoreリポジトリに分離するハイブリッド戦略が現実的です。
以下のスクリプトは、Git LFSが追跡していたファイルリストを識別して対称的なディレクトリ構造を作成し、コピーのSHA-256ハッシュを照合してデータ欠損なくLoreへ移行します。
`bash
#!/usr/bin/env bash
set -euo pipefail
GIT_REPO_DIR="HOME/projects/my-game-lore"
LORE_SERVER_URL="lore://127.0.0.1:41337/my-project"
echo "[1/5] Loreリポジトリの初期化およびリモートバインディング..."
if [ ! -d "LORE_REPO_DIR"
cd "LORE_SERVER_URL"
else
cd "$LORE_REPO_DIR"
fi
echo "[2/5] Git LFS追跡ファイルリストの収集..."
cd "(git lfs ls-files -n | grep -E ".(uasset|umap|fbx|png|psd)$" || true)
if [ -z "$LFS_FILES" ]; then
echo "移行するLFSファイルはありません。"
exit 0
fi
echo "[3/5] ファイルコピーおよび検証用マニフェストの作成..."
echo "filepath" ]; then
dest_dir="(dirname "dest_dir"
cp -p "LORE_REPO_DIR/(openssl dgst -sha256 "$filepath" | awk '{print 2}')
echo "filepath:LORE_REPO_DIR/.lore_migration_manifest"
fi
done
echo "[4/5] Git LFSの解除およびLoreへのステージング..."
cd "LFS_FILES" | while read -r filepath; do
git rm --cached "$filepath"
done
sed -i.bak -E 's/filter=lfs diff=lfs merge=lfs//g' .gitattributes
cd "LFS_FILES" | while read -r filepath; do
lore stage "$filepath"
done
lore commit -m "Migration: Transfer heavy assets from Git LFS to Lore"
lore push
echo "[5/5] データ整合性の検証..."
lore repository verify state
lore repository verify fragment
if [ -f ".lore_migration_manifest" ]; then
migration_errors=0
while IFS=":" read -r file sha; do
if [ -f "(openssl dgst -sha256 "$file" | awk '{print 2}')
if [ "sha" != "$current_hash" ]; then
echo "汚染されたファイルを検知: ((migration_errors + 1))
fi
fi
done < .lore_migration_manifest
if [ $migration_errors -eq 0 ]; then
echo "移行完了。すべてのデータが100%整合性を保った状態で復旧されました。"
rm .lore_migration_manifest
else
echo "検証失敗: $migration_errors 件のファイルの整合性に問題があります。"
exit 1
fi
fi
`
ターミナルを開き、上記の内容を migrate.sh として保存します。chmod +x migrate.sh コマンドで実行権限を付与した後、自身のローカルパスに合わせて変数を修正して実行してください。
この作業を終えると、リモートクラウドのLFSストレージ使用量が即座に減少します。エピックゲームズの自社導入事例によると、このブロックレベルの重複排除技術によってインフラ維持コストを50%程度まで削減可能です。
ビルドサイクルのたびに数百ギガバイトのゲームアセット全体を再ダウンロードするパイプラインは、ネットワークカードとディスクI/Oを破壊する主犯です。Loreはビルド時間を短縮するために、仮想ファイルシステムに基づいた遅延復旧(On-demand Hydration)をサポートしています。
最初のクローン段階ではメタデータ構造のチェーンとディレクトリツリーのみをシェルとして複製し、コンパイラがクック(Cook)プロセスで実際のアセットを読み込む際に必要なバイナリチャンクのみを動的にストリーミングしてディスクを埋める方式です。
`yaml
name: Game Project On-Demand Production Build
on:
push:
branches: [ release-candidate ]
env:
LORE_SERVER: "lore://10.0.1.50:41337/game-depot"
SHARED_STORE_PATH: "/var/lib/lore_shared_chunk_store"
WORKSPACE_PATH: "game_build_workspace"
jobs:
assemble-assets:
runs-on: self-hosted
steps:
- name: Persistent Shared Storeの準備
run: |
if [ ! -d "{{ env.SHARED_STORE_PATH }}"
sudo chmod 777 "{{ env.SHARED_STORE_PATH }}"
fi
- name: Shared Cacheを経由したSparse Bare Clone
run: |
lore clone \
--bare \
--use-shared-store \
--shared-store-path "${{ env.SHARED_STORE_PATH }}" \
"${{ env.LORE_SERVER }}" \
"${{ env.WORKSPACE_PATH }}"
- name: ビューフィルタによる不要なシネマティックソースの除外
run: |
cd "${{ env.WORKSPACE_PATH }}"
echo "+ /SourceCode/" > .lore/view
echo "+ /Config/" >> .lore/view
echo "+ /Content/Core_Assets/" >> .lore/view
echo "- /Content/Cinematic_RAW/" >> .lore/view
- name: 必須チャンクのみをローカルディスクに同期
run: |
cd "${{ env.WORKSPACE_PATH }}"
lore sync
- name: Unreal Engine Cookerの実行
run: |
cd "${{ env.WORKSPACE_PATH }}"
./RunUAT.sh BuildCookRun \
-project="$(pwd)/GameProject.uproject" \
-platform=Win64 \
-clientconfig=Development \
-cook -stage -pak -archive
`
ビルド専用サーバーに /var/lib/lore_shared_chunk_store のような永続キャッシュストレージを用意しておくと効果が最大化されます。lore clone --bare コマンドでインデックス情報のみを素早く取得した後、.lore/view フィルタファイルに必要なパスだけを残して lore sync を実行します。この構造を定着させれば、ビルドノードに転送されるトラフィックが通常比で85%以上削減されます。全体のビルド時間は平均30%程度短縮されます。
Unreal Engineの .uasset やレベルマップファイルのようなバイナリアセットは、テキストコードのようにメインブランチで自動マージすることができません。2人のアーティストが同じアセットを同時に修正すると、後からプッシュしたアーティストが前の作業者の作業を上書きして消し去ったり、タイムラインが崩れたりする事故が発生します。
Loreはリモートサーバーの変更不可能な元帳を基準として排他的制御を行うロック(Lock)機能を直接提供しています。
`bash
lore lock acquire Content/Characters/HeroMesh.uasset --branch main
lore lock status Content/Characters/HeroMesh.uasset
lore lock query --branch main --owner developer_artist_03
lore lock release Content/Characters/HeroMesh.uasset --branch main
`
アーティストがファイルに触れる前に lore lock acquire コマンドでロックを占有させるルールを構築する必要があります。修正が終わり、コミットとプッシュがリモート側に無事反映されたら lore lock release でロックを解除し、次の作業者に渡します。
プランナーやアーティストがターミナルコマンドに不慣れな場合は、AnchorpointのようなデスクトップGUIツールに該当パスを連動させ、マウスの右クリックだけでこれらのロックコマンドが実行されるような環境を整えてあげると良いでしょう。
作業環境の仕様に合わせてクライアント設定を調整することで、ファイルI/Oのボトルネックを防ぐことができます。
--direct-file-write および --direct-file-io フラグをオンにし、ガベージコレクションのスケジュール間隔を長くすることで、作業中の突然のディスク占有現象を防ぎます。Loreアーキテクチャ決定会議(ADR-00016)の結果を参照すると、基本圧縮エンジンとしてZstandard Level 6規格を設定するのが効率面で最もバランスが優れています。
| 圧縮アルゴリズムの種類 | データ最終圧縮率 (%) | 圧縮演算速度 (MiB/s) | 展開速度 (MiB/s) | 移植性および特徴 |
|---|---|---|---|---|
| LZ4 Default | 47.6% | 718.7 | 2494.5 | 速度は速いがストレージ容量の無駄が大きい |
| Zstd Level 1 | 34.5% | 602.0 | 1363.1 | 速度と容量保存の適度な妥協点 |
| Zstd Level 6 (推奨) | 28.9% | 136.5 | 1284.9 | スペース削減対比で最高の処理効率を維持 |
| Oodle Kraken 3 (Fast) | 28.2% | 95.6 | 1413.1 | エピックゲームズ独占Oodle依存ライブラリが必要 |
| Oodle Kraken 6 (既存の基本) | 23.9% | 2.2 | 1312.6 | ギガバイト単位の移行時に速度が大幅に低下 |
以前よく使われていたOodle Kraken Level 6は、バックエンドのシリアライズ過程で圧縮処理速度が毎秒2.2 MiBレベルまで低下し、アーティストの退勤前のコミット待ち時間を延ばす主原因となっていました。
一方、Zstd Level 6はOodle Kraken 6に迫る圧縮率を出しながらも、ローカルチャンクブロックの圧縮速度が136.5 MiB/sで、約62倍高速です。海外拠点や在宅勤務者が多く帯域幅の干渉が激しい場合は、ローカルネットワーク内にプロキシエッジキャッシュノードを構成する2層サーバートポロジの構成を検討することをお勧めします。