Git管理大文件需用git lfs:先在仓库内执行git lfs install安装钩子,再用git lfs track指定glob路径(如"models/*.pt")并提交.gitattributes;克隆时用git lfs clone --skip-smudge避免自动下载,历史清理须用git filter-repo而非reset。

Git 本身不适合直接管理大文件,强行提交会导致仓库体积失控、克隆变慢、推送失败,甚至被 GitHub/Gitee 拒绝(如 pack exceeds maximum allowed size)。真正可行的方案不是“避免提交”,而是用 git lfs 把大文件从 Git 历史中逻辑隔离——既保留版本控制能力,又不拖垮性能。
git lfs install 必须在仓库内执行,且只做一次
git lfs install 不是全局生效的命令,它实际是在当前仓库的 .git/hooks/ 下安装 LFS 钩子(如 pre-push),并设置 filter.lfs.* 配置。如果漏掉这步,后续 git add 大文件时不会触发指针替换,文件会以原始二进制形式进入 Git 对象库。
- 必须先进入目标仓库目录再运行,不能在父级或任意路径下执行
- 每个新克隆的仓库都需要单独运行一次(
git lfs install不随 clone 自动继承) - 如果已误提交过大文件,
git lfs install无法回溯修复,需配合git filter-repo清理历史
git lfs track 的路径匹配规则容易写错
git lfs track 接收的是 glob 模式,不是正则,也不支持绝对路径。常见错误包括:
- 写成
git lfs track "./models/*.pt"—— 点斜杠前缀会被忽略,应直接写"models/*.pt" - 写成
git lfs track "**/*.mp4"——**在 .gitattributes 中不被 LFS 支持,只能用*/或多行逐级声明 - 忘记提交
.gitattributes文件 —— 这个文件由git lfs track自动生成,但不会自动git add,必须手动git add .gitattributes并提交,否则其他协作者拉取后 LFS 规则不生效
克隆时跳过大文件下载要加 --skip-smudge
默认 git clone 会立即下载所有 LFS 文件(按指针触发),这对只需要看代码、不跑模型或不渲染资源的场景是浪费。正确做法是:
- 首次克隆用
git lfs clone --skip-smudge <url>,此时所有 LFS 文件都以指针形式保留在工作区(大小约 1KB),不下载真实内容 - 需要某文件时再显式拉取:
git lfs pull --include="models/efficientnet-b4.pt" - 注意:如果已用普通
git clone,再执行git lfs checkout不会重新下载,得先rm models/*.pt && git checkout -- models/触发 smudge
历史中已混入大文件?别用 git reset 回滚
git reset --hard HEAD~1 只能删掉最新提交,但大文件对象仍留在 Git 对象库中(.git/objects/),仓库体积不会减小。真要清理历史,必须用重写工具:
- 推荐
git filter-repo(官方维护、比 BFG 更可靠):git filter-repo --path-glob "*.pt" --invert-paths - 操作前务必完整备份:
git clone --mirror整个仓库,因为重写会改变所有 commit hash - 清理后需强制推送到远程:
git push --force --all && git push --force --tags,所有协作者必须重新 clone
最常被忽略的一点:LFS 不是“设完就完”的一劳永逸方案。每次新增文件类型(比如突然要加 .fbx),都得重新 git lfs track 并提交 .gitattributes;团队成员也得确认自己本地装了 LFS 客户端并运行过 install。没同步好这套链路,大文件照样悄悄进仓库。


















