Git 是分布式版本控制的强大工具,但它最初设计是针对纯文本代码的。当仓库中包含大量大型二进制文件(如高分辨率图像、视频、音频文件、编译产物或数据集)时,Git 的性能会急剧下降,导致克隆(clone)、抓取(fetch)和检出(checkout)操作变得异常缓慢,甚至占用巨大的磁盘空间。
Git Large File Storage (LFS) 是解决这一问题的官方扩展。LFS 的核心思想是将大文件本身存储在远程服务器上(通常与Git Remote Server集成),而在Git仓库中只保留一个轻量级的“指针”文本文件。
1. LFS 工作原理
Git LFS 将实际的大文件内容从 Git 历史记录中分离出来。当你提交一个LFS跟踪的文件时,Git 仓库中存储的不是文件本身,而是一个包含文件SHA-256哈希值、大小等元数据的文本文件(即指针)。当用户克隆仓库时,Git 客户端会读取这些指针,并通过 LFS 客户端按需从 LFS 服务器下载实际的大文件。
2. LFS 安装与初始化
在使用 LFS 之前,需要先安装 LFS 客户端。
2.1 安装 LFS 客户端
LFS 客户端通常通过操作系统的包管理器安装:
- macOS (使用 Homebrew):
brew install git-lfs
- Debian/Ubuntu:
sudo apt install git-lfs
- Windows: 从 Git LFS 官网 下载安装程序。
2.2 在本地仓库中初始化 LFS
安装完成后,进入你的 Git 仓库并执行初始化命令。这会在全局或仓库级别设置必要的 Git 钩子(hooks)。
git lfs install
3. 如何使用 LFS 跟踪大文件
LFS 必须被明确告知哪些文件类型需要被特殊处理。这是通过 git lfs track 命令实现的。
假设你的项目中有很多 .psd 文件和 .zip 压缩包需要使用 LFS 存储。
3.1 跟踪文件类型
# 告诉 LFS 跟踪所有 .psd 文件
git lfs track "*.psd"
# 告诉 LFS 跟踪所有 .zip 文件
git lfs track "*.zip"
执行 git lfs track 后,Git 会自动创建一个或更新 .gitattributes 文件。这个文件指示 Git LFS 如何处理匹配的文件模式。
3.2 检查 .gitattributes 文件
查看 .gitattributes 内容,你会看到类似以下的内容:
*.psd filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
重要步骤: 必须将 .gitattributes 文件提交到仓库中,这样其他协作者才能正确识别 LFS 跟踪的文件。
git add .gitattributes
git commit -m "Configure LFS tracking for PSD and ZIP files"
4. 完整操作示例
以下是如何在一个新仓库中设置 LFS 并提交一个大文件的完整流程。
# 1. 创建并初始化仓库
mkdir project-with-assets
cd project-with-assets
git init
git lfs install
# 2. 创建一个虚拟大文件 (例如 10MB)
# 注意:在 Linux/macOS 上使用 dd;Windows 可以使用 fsutil 或创建 large_file.zip 替代
dd if=/dev/urandom of=high_res_image.jpg bs=1M count=10
# 3. 跟踪文件类型
git lfs track "*.jpg"
# 4. 提交文件
git add .
# 此时,Git LFS 客户端接管了 .jpg 文件的处理
git commit -m "Add large image asset via LFS"
# 5. 设置远程并推送 (假设远程名为 origin)
# git remote add origin <REMOTE_URL>
# git push origin main
# 当你 push 时,LFS 会先将大文件上传到 LFS 服务器,然后将轻量级的指针文件推送到 Git 仓库。
5. LFS 状态检查
你可以使用 git lfs status 命令查看当前有哪些文件正在被 LFS 跟踪,以及哪些文件需要被推送到 LFS 服务器。
git lfs status
6. 迁移现有大文件
如果你的仓库中已经存在很多未经 LFS 跟踪的大文件,并且导致了历史记录臃肿,你可以使用 git lfs migrate 命令来重写历史记录,将这些文件转换为 LFS 指针。这是一个高级操作,需要谨慎进行,因为它会更改历史提交的 SHA 值。
示例:将所有历史上的 .mp4 文件迁移到 LFS
# 检查哪些文件可以被迁移
git lfs migrate info --everything
# 执行迁移(危险操作,请先备份)
git lfs migrate import --everything --include="*.mp4"
# 强制推送到远程 (因为历史已被重写)
# git push --force origin main
通过 Git LFS,团队可以高效地管理包含大量二进制资源的项目,显著加速克隆和检出时间,使 Git 保持其核心优势:高效处理文本代码。
汤不热吧