Git LFS vs. 标准 Git:大型资产的性能对比
比较 Git LFS 与标准 Git 在处理大型资产时的表现,包括克隆行为、指针文件、LFS 跟踪机制以及何时值得使用 LFS。
Git LFS vs. 标准 Git:大型资产的性能对比
当你的仓库开始包含大型二进制资产时,Git LFS 与标准 Git 的选择就成为一个实际问题。源代码通常能很好地压缩和差异比较,但视频、设计文件、游戏纹理、模型文件和大型数据集会使克隆变慢,历史记录也难以清理。
Git 大文件存储(通常称为 Git LFS)通过将选定的文件替换为小型指针文件,并将实际内容存储在 LFS 对象存储中,来保持普通 Git 仓库的轻量化。这种权衡对许多团队有帮助,但它并非万能。你仍然需要选择合适的文件、提交跟踪规则,并了解 LFS 何时下载内容。
标准 Git 的性能瓶颈
标准 Git 将提交的内容存储在其对象数据库中,并保留足够的历史记录以重建每个提交的版本。这对文本文件非常有效。但当同一个 200 MB 的二进制文件多次更改时,效果就很差。
两个问题会迅速显现:
- JPEG、MP4、ZIP、PSD 和编译产物等二进制格式通常无法很好地增量压缩。
- 除非重写历史,否则已删除的文件会保留在历史记录中。
- 新的克隆会为过去的错误付出代价,因为 Git 历史仍然包含那些旧对象。
- 仓库维护命令需要检查和处理更多数据。
例如,如果一个团队每个冲刺都提交一个大型导出的设计文件,稍后从当前分支删除该文件并不会移除其旧版本。新的开发者和 CI 工作进程可能仍会下载无人实际使用的数据。
引入 Git 大文件存储 (LFS)
Git LFS 是一个扩展,用于在普通 Git 对象数据库之外管理选定的文件。你的仓库保留一个小的文本指针。实际文件内容存储在由你的 Git 托管平台或其他 LFS 服务器提供的 LFS 存储中。
指针系统
一个 LFS 指针看起来像这样:
version https://git-lfs.github.com/spec/v1
oid sha256:4c2d44962ff3c43734e56598c199589d8995a643...a89c89
size 104857600
普通 Git 看到的就是这个指针。当检出或显式 LFS 命令需要时,Git LFS 客户端会下载实际文件内容。
性能对比:LFS vs. 标准 Git
| 操作 | 标准 Git | Git LFS |
|---|---|---|
| 初始克隆 | 下载包含已提交大型对象的 Git 历史 | 下载包含指针文件的 Git 历史;LFS 内容可能根据配置在检出时下载 |
| 仓库增长 | 大型二进制文件可能膨胀 .git 历史 |
Git 历史保持较小,因为跟踪的文件内容是外部的 |
| 检出 | 使用已存在于 Git 数据库中的对象 | 可能需要为检出的提交获取 LFS 对象 |
| CI 作业 | 可能浪费下载历史资产的时间 | 当构建不需要资产时,可以跳过或限制 LFS 下载 |
| 清理 | 需要重写历史以移除旧的已提交 blob | 仍需注意,但新的 LFS 跟踪版本不会膨胀普通 Git 历史 |
重要的细节是检出行为。安装了 Git LFS 后,普通的 git clone 通常会下载检出提交所需的 LFS 文件。如果你只想要指针,可以在克隆时使用 GIT_LFS_SKIP_SMUDGE=1,稍后使用 git lfs pull 获取文件。
何时使用 Git LFS
Git LFS 适用于大型、二进制且预期会更改的文件。常见示例包括:
*.psd、*.tiff、*.blend以及其他设计或 3D 资产。*.mp4、*.mov、*.wav以及其他媒体文件。- 项目所需的大型模型文件、测试夹具或数据集。
- 仅当项目有明确理由进行版本控制时的编译二进制文件。
不要仅仅因为可以就把每个文件都放入 LFS。文本文件、源代码、小型配置文件以及你希望 Git 正常差异比较的文件应保留在标准 Git 中。
在采用 LFS 之前,请检查你的托管服务提供商的存储和带宽限制。GitHub、GitLab、Bitbucket 和自托管平台在配额、计费和保留策略方面可能有所不同。
实施 Git LFS
安装 Git LFS 客户端,然后为你的用户启用其钩子:
git lfs install
跟踪你希望 LFS 管理的模式:
git lfs track "*.psd"
git lfs track "assets/*.mp4"
这些命令会创建或更新 .gitattributes。将该文件与其影响的资产一起提交:
git add .gitattributes assets/
git commit -m "使用 Git LFS 跟踪设计资产"
git push
如果一个大文件已经提交到普通 Git 历史中,使用 LFS 跟踪它只会影响未来的提交。要迁移现有历史,请使用诸如 git lfs migrate import 之类的迁移工具,并仔细协调,因为重写历史会更改提交 ID。
要克隆而不立即下载 LFS 内容,请使用:
GIT_LFS_SKIP_SMUDGE=1 git clone [email protected]:example/assets-heavy-repo.git
cd assets-heavy-repo
git lfs pull --include="assets/*.mp4"
实用要点
对源代码和小型文本文件使用标准 Git。对属于仓库但不应膨胀普通 Git 历史的大型二进制资产使用 Git LFS。
对于团队仓库,尽早添加 LFS 规则,提交 .gitattributes,记录 CI 如何处理 LFS 下载,并验证你的托管平台的 LFS 限制。这样可以在克隆、检出或发布构建时获得性能优势,而不会让开发者感到意外。