本文主要介绍 Git LFS(Large File Storage)的工作方式、常用客户端命令,以及在 Gitea 上开启 LFS 时的 app.ini 要点。
Git 对大体积二进制文件不友好:每次变更都会在对象库中留下难以增量压缩的 blob,导致 clone/fetch 变慢、仓库膨胀。LFS 用指针文件进入 Git 历史,实体文件放到独立 LFS 存储,由客户端在 checkout/push 时透明上下传。
核心概念
| 点 | 说明 |
|---|---|
| 指针文件 | 仓库中保存的小文本,指明 OID、大小等 |
| LFS 存储 | 实际大文件所在位置(本地盘、MinIO、云存储等) |
| 钩子 / smudge-clean | 在 add/checkout 时在指针与实体间转换 |
| 服务端 | 托管平台需开启 LFS API(GitHub/GitLab/Gitea 等) |
工作流示意:
git add 大文件
→ LFS 识别 track 规则
→ 实体上传 LFS 存储,Git 只提交指针
git checkout / clone
→ 按需从 LFS 拉取实体(可 skip smudge 只留指针)
适合 / 不适合
适合:设计源文件、高清媒体、大型压缩包、数据集、少改动的二进制产物等。
不适合:源码与文本配置、频繁小改的小文件(LFS 增加链路复杂度,收益小)。
客户端常用命令
安装与环境
git lfs install
git lfs version
git lfs env
install 会在本机配置 Git 过滤器与钩子,每个开发者机器通常都需要执行一次。
跟踪规则
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "assets/**"
git lfs track
git lfs ls-files
track 会改写 .gitattributes,需一并提交:
git add .gitattributes
git commit -m "chore: configure Git LFS tracking"
.gitattributes 片段示例:
*.psd filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
日常提交与同步
git add .
git commit -m "Add large assets"
git push origin main
git lfs status
git lfs pull
git lfs push origin main
多数情况下 git push/git pull 已足够;网络或权限异常时可显式 git lfs push/pull。
维护与迁移
git lfs ls-files --all
git lfs ls-files --long
git lfs prune
git lfs fetch --all
git lfs push --all origin
# 将已在 Git 历史中的文件迁入 LFS(会改写历史,需团队评估)
git lfs migrate import --include="*.psd,*.ai" --everything
克隆策略
git clone <repo-url>
# 只拉指针,稍后再拉实体
GIT_LFS_SKIP_SMUDGE=1 git clone <repo-url>
git lfs pull --include="path/to/file.psd"
可选全局参数
git config --global lfs.dialtimeout 300
git config --global lfs.concurrenttransfers 8
按网络与磁盘能力调整,勿盲目加大并发。
初始化示例
git lfs install
git lfs track "*.psd"
git lfs track "assets/videos/*.mp4"
git add .gitattributes
git commit -m "Configure Git LFS tracking"
git add large-file.psd
git commit -m "Add design file"
git push origin main
推送成功后,在支持 LFS 的托管 UI 中,对象详情或仓库「LFS」页应能看到对应文件(Gitea 见下节)。
Gitea 服务端配置
配置文件一般为 custom/conf/app.ini(或发行包约定的 conf 路径)。完整项见 app.example.ini。
[server] 开启 LFS
[server]
LFS_START_SERVER = true
LFS_ALLOW_PURE_SSH = true
; 务必自行生成,勿使用空值或公开示例
LFS_JWT_SECRET = <generate-a-secret>
LFS_MAX_FILE_SIZE = 0
LFS_LOCKS_PAGING_NUM = 50
LFS_MAX_BATCH_SIZE = 0
LFS_HTTP_AUTH_EXPIRY = 24h
LFS_MAX_FILE_SIZE = 0 表示不在此限制单文件大小(仍可能受反代/磁盘约束)。生产建议设明确上限。
[lfs] 与 [lfs_client]
[lfs]
STORAGE_TYPE = local
PATH = /data/git/lfs
SERVE_DIRECT = false
; STORAGE_TYPE = minio 时还可配 MINIO_* / SERVE_DIRECT 等,见官方示例
[lfs_client]
BATCH_SIZE = 20
BATCH_OPERATION_CONCURRENCY = 8
STORAGE_TYPE 除 local 外可对接 MinIO、Azure Blob 等(版本以当前 Gitea 文档为准)。改完后重启 Gitea 使配置生效。
验证
- 客户端
git lfs env指向的 endpoint 为该 Gitea。 - 推送 LFS 对象后,在仓库 Web UI 中文件信息含 LFS 标识,仓库设置中有 LFS 对象列表(历史截图资产若需上站,迁到
assets/posts/再链)。
注意事项
- 全员安装 LFS;未装 LFS 的机器可能只看到指针文本或提交异常。
- 关注托管侧 LFS 存储配额 与备份(LFS 对象不在普通 git bundle 的同一路径上)。
migrate import会改写历史,流程类似历史瘦身,需 force push 与协作约定。- 与「误提交大文件后 untrack」不同:LFS 是从一开始就避免大 blob 进 Git 对象库。