TuBrief
구독 채널
비디오
커뮤니티

解决 Git LFS 成本爆炸与虚幻引擎资产冲突的 Lore VCS 迁移指南

TuBrief 편집팀
2026년 7월 14일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

中文한국어EnglishEspañolالعربيةDeutschFrançaisPortuguêsहिन्दीРусскийBahasa Indonesia日本語

관련 영상

Git 处理不了游戏……所以 Epic 开发了 Lore7:44

Git 处理不了游戏……所以 Epic 开发了 Lore

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

解决 Git LFS 成本爆炸与虚幻引擎资产冲突的 Lore VCS 迁移指南

当项目规模扩大时,Git LFS 就会变成一场灾难。修改几行源代码只需瞬间,但一旦开始掺杂千兆字节(GB)级的艺术资产,每次提交都会让鼠标指针转上半天沙漏。由于 LFS 将大文件整块复制并堆积的迟钝结构,存储库容量很快就会超过数太字节(TB),带宽账单上的数字也会变得触目惊心。

Epic Games 开源的 Lore 将二进制文件放在首位。它使用 FastCDC 方式将文件切分为块并消除重复,从而显著降低了包体积和传输带宽。即使是缺乏 DevOps 专业人员的小型团队,也能立即应用本文总结的 Lore 实战迁移与优化方法。


1. 从 Git LFS 逐步迁移到 Lore

没有必要非要抛弃现有 Git 存储库中积累的源代码提交历史。将轻量级的代码保留在 Git 中,仅将笨重的二进制资产分离到 Lore 存储库中,是一种切实可行的混合策略。

下面的脚本识别出 Git LFS 追踪的文件列表,创建对称的目录结构,并对照副本的 SHA-256 哈希值,确保在不丢失数据的情况下迁移到 Lore。

`bash
#!/usr/bin/env bash
set -euo pipefail

GIT_REPO_DIR="HOME/projects/my−game−git"LOREREPODIR="HOME/projects/my-game-git" LORE_REPO_DIR="HOME/projects/my−game−git"LORER​EPOD​IR="HOME/projects/my-game-lore"
LORE_SERVER_URL="lore://127.0.0.1:41337/my-project"

echo "[1/5] 初始化 Lore 存储库及远程绑定..."
if [ ! -d "LOREREPODIR"];thenmkdir−p"LORE_REPO_DIR" ]; then mkdir -p "LORER​EPOD​IR"];thenmkdir−p"LORE_REPO_DIR"
cd "LOREREPODIR"lorerepositorycreate"LORE_REPO_DIR" lore repository create "LORER​EPOD​IR"lorerepositorycreate"LORE_SERVER_URL"
else
cd "$LORE_REPO_DIR"
fi

echo "[2/5] 收集 Git LFS 追踪文件列表..."
cd "GITREPODIR"LFSFILES=GIT_REPO_DIR" LFS_FILES=GITR​EPOD​IR"LFSF​ILES=(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 "LFSFILES"∣whileread−rfilepath;doif[−f"LFS_FILES" | while read -r filepath; do if [ -f "LFSF​ILES"∣whileread−rfilepath;doif[−f"filepath" ]; then
dest_dir="LOREREPODIR/LORE_REPO_DIR/LORER​EPOD​IR/(dirname "filepath")"mkdir−p"filepath")" mkdir -p "filepath")"mkdir−p"dest_dir"
cp -p "filepath""filepath" "filepath""LORE_REPO_DIR/filepath"sourcehash=filepath" source_hash=filepath"sourceh​ash=(openssl dgst -sha256 "$filepath" | awk '{print 2}') echo "filepath:sourcehash">>"source_hash" >> "sourceh​ash">>"LORE_REPO_DIR/.lore_migration_manifest"
fi
done

echo "[4/5] 解除 Git LFS 追踪并暂存到 Lore..."
cd "GITREPODIR"echo"GIT_REPO_DIR" echo "GITR​EPOD​IR"echo"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 "LOREREPODIR"echo"LORE_REPO_DIR" echo "LORER​EPOD​IR"echo"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 "file"];thencurrenthash=file" ]; then current_hash=file"];thencurrenth​ash=(openssl dgst -sha256 "$file" | awk '{print 2}') if [ "sha" != "$current_hash" ]; then
echo "检测到受损文件: file"migrationerrors=file" migration_errors=file"migratione​rrors=((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 的存储使用量将立即减少。根据 Epic Games 的内部应用案例,通过这种块级去重技术,可将基础设施维护成本降低 50% 左右。


2. 在 CI/CD 流水线中应用按需加载(On-demand Hydration)

每个构建周期都重新下载数百 GB 的完整游戏资产的流水线,是摧毁网卡和磁盘 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: 准备持久化共享存储
run: |
if [ ! -d "env.SHAREDSTOREPATH"];thensudomkdir−p"{{ env.SHARED_STORE_PATH }}" ]; then sudo mkdir -p "env.SHAREDS​TOREP​ATH"];thensudomkdir−p"{{ env.SHARED_STORE_PATH }}"
sudo chmod 777 "env.SHAREDSTOREPATH"loreshared−storecreate"{{ env.SHARED_STORE_PATH }}" lore shared-store create "env.SHAREDS​TOREP​ATH"loreshared−storecreate"{{ env.SHARED_STORE_PATH }}"
fi

  - name: 经由共享缓存进行稀疏裸克隆(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: 执行虚幻引擎 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%。


3. 使用文件锁定系统防止资产冲突

虚幻引擎的 .uasset 或关卡地图文件等二进制资产,不像文本代码那样可以在主分支中自动合并。如果两名艺术家同时修改同一个资产,就会发生事故:后推送的人覆盖了前一个人的工作,导致工作丢失或时间线错乱。

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 工具关联,只需鼠标右键点击即可执行这些锁定命令,从而构建良好的环境。


4. 不同硬件配置下的缓存调优指南

应根据工作环境的规格调整客户端设置,以防止文件 I/O 瓶颈。

不同配置 PC 的本地客户端调优

  • 高性能系统 (NVMe SSD, 32GB RAM 以上, 多核 CPU): 通过 OS 内存映射技术,允许基于内存映射的直接操作。为了消除同步延迟,扩展最大并行下载连接线程,并延长磁盘缓存保留期限。
  • 入门级及艺术家系统 (SATA SSD 或 HDD, 16GB 以下 RAM): 为防止内存耗尽导致的引擎崩溃,关闭内存映射方式。开启 --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 需要 Epic Games 独家 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 倍。如果海外分公司或居家办公人员较多,带宽干扰严重,建议考虑构建双层服务器拓扑,在本地网络内配置代理边缘缓存节点。