Git仓库迁移至LFS后体积未按预期缩小的问题排查
问题原因
你遇到的体积未达预期问题,核心是三个认知和操作偏差:
git lfs migrate import --everything会将**所有可达引用(含全部分支、标签、reflog留存的悬空提交、远程跟踪分支)**中匹配规则的文件全部转换为LFS指针,只要这些提交还在Git的引用链上,对应的LFS对象就会被判定为「正在使用」,不会被默认参数的git lfs prune清理。你留存的5个历史版本大文件,本质是对应旧提交没有被剔除出引用链,而非迁移失败。- git-lfs 2.13版本的默认
prune逻辑,仅会清理超过保留时长、且不存在于任何本地检出提交、也不存在于任何已推送远程引用的LFS对象。只要旧提交还挂在分支提交历史中,对应LFS对象就会被保留,自然不会收缩到仅存最新版本的大小。 - 旧版Bitbucket不会自动清理无引用的LFS对象。你之前强制推送后重新克隆体积仍达15GB,是因为远程仓库还留存着首次推送时上传的全量历史LFS对象,没有触发垃圾回收,克隆时会拉取所有当前分支历史可达的LFS对象。
适配环境的解决步骤
以下操作适配git-lfs 2.13 + 旧版Bitbucket环境,执行前请先备份本地仓库,避免历史误改无法恢复。
注意:操作完成后,旧提交对应的大文件将从本地和远程存储中永久删除,checkout到历史提交时无法拉取对应版本的大文件,仅能正常访问最新提交中的大文件,请确认你不需要回溯旧版大文件后再执行。
- 第一步:清理本地冗余引用,避免无效提交被带入迁移流程
# 清空所有本地reflog记录,清除悬空提交引用 git reflog expire --expire=now --all # 同步远程引用状态,清理本地失效的远程跟踪分支 git fetch origin --prune # 手动删除本地不需要保留的分支、标签,仅保留需要迁移的有效分支 - 第二步:重新执行LFS迁移,不要使用
--everything参数,明确指定需要迁移的分支范围,比如仅迁移主分支:# 替换main为你实际使用的主分支名,若有其他需要保留的分支可追加多个--include-ref参数 git lfs migrate import --include="big-file-folder/**" --include-ref=refs/heads/main - 第三步:检出主分支最新提交,强制清理本地冗余LFS对象
git checkout main # 跳过默认保留规则,清理所有不在当前HEAD提交中的LFS对象,同时校验远程对象状态避免误删 git lfs prune --verify-remote --force # 执行后可通过以下命令验证LFS存储大小,此时本地LFS体积应接近2.5GB du -sm .git/lfs - 第四步:强制推送重写后的仓库历史到远程
# 强制推送所有分支 git push origin --force --all # 强制推送所有标签 git push origin --force --tags - 第五步:登录Bitbucket仓库后台,手动触发仓库垃圾回收,清理远程存储中无引用的旧Git对象和LFS对象。旧版Bitbucket没有自动GC机制,必须手动触发才会删除已经失效的历史大文件。
- 第六步:等待GC完成后,重新在新目录克隆仓库,新克隆的仓库默认仅拉取最新提交对应的LFS对象,整体体积会降到你预期的3GB左右。如果克隆后体积仍有偏差,在新仓库内执行一次
git lfs prune --verify-remote即可。
内容的提问来源于stack exchange,提问作者Jozef Chocholacek
相关产品推荐
相关产品推荐

