Git LFS 大文件存储
Git Large File Storage (LFS) 是 Git 的一个扩展,专门用于处理大文件。Git 本身不适合管理大型二进制文件,因为每次修改都会生成完整的副本,导致仓库体积迅速膨胀。Git LFS 通过将大文件存储在远程服务器上,而在 Git 仓库中只保留指向这些文件的轻量级引用,解决了这个问题。
为什么需要 Git LFS?
Git 存储大文件的问题
Git 的设计初衷是管理文本文件(源代码),对于二进制大文件存在以下问题:
- 仓库体积膨胀:每次修改二进制文件,Git 都会存储完整的副本,而不是差异
- 克隆变慢:大文件会让克隆和拉取变得非常缓慢
- 网络带宽浪费:即使只修改了一小部分,也要传输整个文件
- 磁盘空间占用大:历史版本都会保留完整副本
Git LFS 的解决方案
Git LFS 的工作原理:
- 在提交时,将大文件替换为一个轻量级的指针文件
- 大文件的实际内容存储在 LFS 服务器上
- 在检出时,LFS 自动下载指针指向的实际文件内容
安装 Git LFS
Windows
# 使用 winget
winget install Git.Git.LFS
# 或下载安装包
# https://git-lfs.github.com/
macOS
# 使用 Homebrew
brew install git-lfs
# 使用 MacPorts
port install git-lfs
Linux
# Debian/Ubuntu
sudo apt update
sudo apt install git-lfs
# CentOS/RHEL
sudo yum install git-lfs
# Fedora
sudo dnf install git-lfs
# Arch Linux
sudo pacman -S git-lfs
初始化
安装后,需要为当前用户初始化 Git LFS:
git lfs install
# 输出
Git LFS initialized.
这个命令会在你的全局 Git 配置中添加必要的设置,只需运行一次。
基本使用
1. 追踪大文件
告诉 Git LFS 哪些文件需要使用 LFS 管理:
# 追踪特定扩展名的文件
git lfs track "*.psd"
# 追踪特定文件
git lfs track "assets/video.mp4"
# 追踪某个目录下的所有文件
git lfs track "assets/**"
# 追踪所有大于 100KB 的文件
git lfs track --filename="*.bin" --above=100KB
2. 查看 LFS 追踪规则
# 查看当前追踪规则
git lfs track
# 输出示例
Listing tracked patterns
*.psd (.gitattributes)
*.mp4 (.gitattributes)
assets/** (.gitattributes)
3. 提交追踪规则
git lfs track 命令会在项目根目录创建或更新 .gitattributes 文件,这个文件需要提交到仓库:
# 查看 .gitattributes 内容
cat .gitattributes
# 输出示例
*.psd filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
assets/** filter=lfs diff=lfs merge=lfs -text
# 提交 .gitattributes
git add .gitattributes
git commit -m "配置 Git LFS 追踪规则"
4. 正常提交大文件
配置好后,正常使用 Git 命令即可,LFS 会自动处理:
# 添加大文件
git add design.psd
# 提交
git commit -m "添加设计稿"
# 推送
git push origin main
5. 查看文件状态
# 查看 LFS 文件状态
git lfs ls-files
# 输出示例
d4e5f6g7 - design.psd
a1b2c3d4 - video.mp4
工作原理详解
指针文件
Git LFS 用指针文件替换大文件,指针文件是一个文本文件,包含实际文件的引用信息:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345678
version:LFS 规范版本oid:对象 ID,通常是文件内容的 SHA-256 哈希size:文件大小(字节)
工作流程
Clean/Smudge 过滤器
Git LFS 使用 Git 的 clean/smudge 过滤器机制:
- Clean 过滤器:在
git add时触发,将大文件转换为指针 - Smudge 过滤器:在
git checkout时触发,将指针还原为大文件
这由 .gitattributes 中的配置驱动:
*.psd filter=lfs diff=lfs merge=lfs -text
filter=lfs:使用 LFS 过滤器diff=lfs:使用 LFS 进行差异比较merge=lfs:使用 LFS 进行合并-text:标记为二进制文件
常用命令
文件管理
# 追踪文件
git lfs track "*.extension"
# 取消追踪
git lfs untrack "*.extension"
# 查看已追踪的文件
git lfs track
# 列出当前 LFS 管理的文件
git lfs ls-files
# 查看文件信息
git lfs pointer --file=large-file.bin
数据传输
# 推送 LFS 对象到服务器
git lfs push --all origin
# 推送特定分支的 LFS 对象
git lfs push origin main
# 从服务器拉取 LFS 对象
git lfs pull
# 获取 LFS 对象信息但不下载
git lfs fetch
# 检出 LFS 文件
git lfs checkout
数据迁移
# 将历史提交中的大文件迁移到 LFS
git lfs migrate import --include="*.psd" --everything
# 只迁移特定分支
git lfs migrate import --include="*.psd" --include-ref=refs/heads/main
# 导出 LFS 文件到普通 Git 对象
git lfs migrate export --include="*.psd" --everything
信息查看
# 查看 LFS 配置
git lfs env
# 查看 LFS 对象信息
git lfs objects
# 查看 LFS 日志
git lfs logs
# 查看 LFS 存储使用情况
git lfs du
迁移现有仓库到 LFS
如果你已经有一个包含大文件的仓库,可以将历史大文件迁移到 LFS。
方法一:使用 git lfs migrate
这是推荐的方法,会重写 Git 历史:
# 迁移所有历史中的 .psd 文件
git lfs migrate import --include="*.psd" --everything
# 迁移多种文件类型
git lfs migrate import --include="*.psd,*.mp4,*.zip" --everything
# 只迁移 main 分支
git lfs migrate import --include="*.psd" --include-ref=refs/heads/main
# 迁移最近的 N 次提交
git lfs migrate import --include="*.psd" --above=1MB HEAD~10..HEAD
迁移完成后,需要强制推送:
# 强制推送(会重写历史)
git push --force --all
git push --force --tags
警告:迁移会重写 Git 历史,所有协作者需要重新克隆仓库。
方法二:手动迁移
对于不想重写历史的情况,可以只对新提交使用 LFS:
# 1. 配置 LFS 追踪
git lfs track "*.psd"
git add .gitattributes
git commit -m "配置 LFS"
# 2. 从 Git 中移除大文件
git rm --cached large-file.psd
# 3. 重新添加(这次会使用 LFS)
git add large-file.psd
git commit -m "迁移大文件到 LFS"
git push
这种方法不会减少历史仓库的体积,但之后的大文件会用 LFS 管理。
托管服务支持
GitHub
GitHub 对 LFS 提供良好支持:
- 免费账户:1 GB 存储空间,每月 1 GB 带宽
- 付费计划:可购买额外存储和带宽
# 查看当前仓库的 LFS 使用情况
gh api repos/{owner}/{repo}/content-references
GitLab
GitLab 也支持 LFS:
- 自托管:无限制
- GitLab.com:免费账户有配额限制
配置 .lfsconfig:
[lfs]
url = https://gitlab.example.com/group/project.git/info/lfs
自建 LFS 服务器
可以使用开源的 LFS 服务器实现:
配置自定义 LFS 服务器:
# 为仓库配置 LFS URL
git config lfs.url https://lfs.example.com/owner/repo
# 或在 .lfsconfig 中配置
[lfs]
url = https://lfs.example.com/owner/repo
最佳实践
1. 选择合适的文件类型
Git LFS 适合以下类型的文件:
- 设计文件:
.psd、.ai、.sketch - 视频文件:
.mp4、.mov、.avi - 音频文件:
.mp3、.wav、.flac - 3D 模型:
.obj、.fbx、.blend - 数据集:
.csv(大型)、.parquet - 压缩包:
.zip、.tar.gz - 二进制文件:
.exe、.dll、.so
2. 合理设置追踪规则
# 推荐:按扩展名追踪
git lfs track "*.psd"
# 不推荐:追踪所有大文件(可能误伤代码文件)
# git lfs track --above=100KB
3. 提交 .gitattributes
确保 .gitattributes 文件被提交到仓库,这样所有协作者都能使用相同的 LFS 配置:
git add .gitattributes
git commit -m "添加 LFS 配置"
4. 团队协作注意事项
- 所有团队成员都需要安装 Git LFS
- 迁移历史时通知所有协作者重新克隆
- 定期检查 LFS 存储使用情况
5. 锁定大文件(可选)
对于不适合合并的二进制文件,可以使用锁定功能:
# 锁定文件
git lfs lock design.psd
# 查看锁定的文件
git lfs locks
# 解锁文件
git lfs unlock design.psd
常见问题解决
问题:推送时 LFS 文件没有上传
# 手动推送 LFS 对象
git lfs push --all origin
# 或重新安装 LFS 钩子
git lfs install --force
问题:克隆后 LFS 文件没有下载
# 手动拉取 LFS 文件
git lfs pull
# 检查 LFS 配置
git lfs env
问题:迁移后仓库体积没有减小
# 清理旧的 reflog 和垃圾对象
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# 检查仓库大小
git count-objects -vH
问题:LFS 配额不足
# 查看当前使用情况
git lfs du
# 删除不需要的历史 LFS 对象(需要迁移重写历史)
git lfs migrate import --include="*.psd" --above=10MB --everything
.gitattributes 示例
# 设计文件
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.sketch filter=lfs diff=lfs merge=lfs -text
# 视频文件
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
# 音频文件
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
# 压缩包
*.zip filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text
# 二进制文件
*.exe filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
# 数据文件
*.parquet filter=lfs diff=lfs merge=lfs -text
小结
本章我们学习了:
- Git LFS 的作用:解决 Git 管理大文件的问题
- 安装和配置:在不同平台安装 Git LFS
- 基本使用:追踪文件、提交、推送
- 工作原理:指针文件、clean/smudge 过滤器
- 迁移现有仓库:使用
git lfs migrate - 托管服务支持:GitHub、GitLab、自建服务器
- 最佳实践:选择文件类型、团队协作