Git删除包含大文件的历史提交

45 阅读2分钟

1 概述

🤷‍♂️ 我们的历史提交中有不同版本的大文件,即使之后把此文件删除,那么这个文件的历史版本也会存在在历史版本中,如果此文件巨大,则 .git 管理目录就会巨大,占据磁盘空间巨大,clone 缓慢

2 解决方案

2.1 使用 git-filter-repo

🚀 步骤:

  1. 安装 git-filter-repo
# Python 需 >= 3.5 
pip install git-filter-repo
  1. 安全起见,备份原仓库
cp -r your-repo your-repo-backup
  1. 在有 .git 的目录 执行 分析, 它会在 .git/filter-repo/analysis/ 目录下生成多个分析报告,清晰列出大文件及其 SHA 和路径
git filter-repo --analyze
  1. 查看分析一下文件,找出size巨大的文件
    • blob-shas-and-paths.txt :
    • path-all-sizes.txt : 显示文件历史版本 累计占用
    • path-deleted-sizes.txt
  2. 删除历史提交中的大文件
# 进入你的仓库根目录
cd your-repo

# 执行过滤:删除所有历史中出现过的 Go4droid/app/src/main/res/raw/files.zip
git filter-repo --path Go4droid/app/src/main/res/raw/files.zip --invert-paths

👩‍💻 执行后console输出:

NOTICE: Removing 'origin' remote; see 'Why is my origin removed?' in the manual if you want to push back there. (was git@github.com:xxx/Go4droid.git) Parsed 59 commits New history written in 0.29 seconds; now repacking/cleaning...

🚩注意: 这是为了安全防止你强制push,造成不可挽回的后果,工具帮你删除了 origin 远程仓库的引用,需要你主动恢复远程仓库地址

git remote add origin git@github.com:xxx/Go4droid.git
  1. 强制推送新历史到远程仓库
git push --force --all origin
git push --force --tags origin

注意: 这会覆盖远程历史,请确保

  • 没有其他人正在基于旧历史开发
  • 或已通知协作者备份/重新 clone
  1. 验证仓库大小, 使用 git-sizer1
git-sizer

3 建议

🛡️ 长期建议: 防止再次发生

  1. 添加 .gitignore: 确保大文件、临时文件、构建产物不被提交
  2. 改用 Git LFS (如果确实需要版本控制大文件):
git lfs install

git lfs track "Go4droid/**/*.zip"
# git lfs track "*.mp4" "*.bin"

git add .gitattributes

Footnotes

  1. github.com/github/git-…