欢迎光临
我们一直在努力

如何清理 Git 仓库中的大文件残留:彻底释放 .git 文件夹占用的磁盘空间

为什么 .git 文件夹会变得异常庞大?

在使用 Git 进行版本控制的过程中,我们可能会不小心提交一些大型文件,例如编译产物、数据库备份、视频文件或大型数据集。即使您后来将这些大文件从工作目录中删除并提交了新的版本,Git 的历史记录(存在于 .git 文件夹中)仍然保留着这些文件的所有版本。如果不清理历史记录,.git 文件夹就会持续膨胀,导致克隆速度变慢,并占用大量磁盘空间。

本文将指导您如何使用现代化且高效的工具 ****git filter-repo**** 来彻底重写历史记录,移除残留的大文件。

警告: 清理 Git 历史记录是破坏性操作,它会改变所有提交的 SHA-1 值。在进行操作之前,请务必备份您的仓库,并与团队成员沟通,因为所有协作者都需要重新克隆仓库。


准备工作:安装 git filter-repo

git filter-repo 是 Git 官方推荐的用于历史重写的工具,它比老旧的 git filter-branch 更快、更安全。它依赖 Python 环境。

# 确保您安装了 Python 和 pip
pip install git-filter-repo

步骤一:找出仓库中的“幽灵”大文件

首先,我们需要知道哪些文件在历史记录中占据了最大的空间。以下命令可以帮助您列出仓库中历史记录最大的 10 个文件:

git rev-list --objects --all | grep "^$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10 | awk '{print $1}')"

# 或者,使用更直观的脚本来分析大小(此脚本需要 Linux/macOS 环境)
git rev-list --objects --all \n| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \n| awk '/^blob/ {print $3, $4}' \n| sort -n -r \n| head -n 10

运行上述命令后,您将看到文件大小和对应的路径,例如:

104857600 path/to/large_data_file.zip
52428800 old_video_asset.mp4
... (其他大文件)

假设我们确定要删除 large_data_file.zip 和所有 *.mp4 文件。

步骤二:使用 git filter-repo 重写历史记录

进入您的 Git 仓库根目录,然后执行删除操作。

重要: git filter-repo 必须在一个“干净”的副本上运行。我们通常建议您先克隆一个新的本地副本(不带任何远程跟踪)来进行此操作。

1. 克隆一个干净的本地仓库(可选,但推荐)

cd ..
git clone --mirror your_original_repo your_repo_clean
cd your_repo_clean

2. 执行删除操作

现在,使用 –invert-paths–path 选项来指定要排除的文件,或者使用 –path-glob 来指定模式。确保您的操作目标是精确的文件名和路径。

示例:删除特定的 ZIP 文件和所有的 MP4 文件

git filter-repo --path large_data_file.zip --path-glob '*.mp4' --invert-paths

这条命令的意思是:“保留所有路径,除了 large_data_file.zip 和所有 *.mp4 文件。” git filter-repo 会自动遍历所有分支和标签,并重写提交历史,将这些文件彻底清除。

步骤三:清理和回收磁盘空间

仅仅重写历史记录是不够的,被删除的大文件仍然存储在 Git 的引用日志(reflog)和未引用的对象中。我们需要强制 Git 进行垃圾回收。

  1. 清理引用日志 (Reflog): 确保 Git 丢弃所有对旧提交的引用。
git reflog expire --expire=now --all
  1. 执行垃圾回收 (Garbage Collection): 强制 Git 立即打包对象并移除未引用的对象,以释放空间。
git gc --prune=now --aggressive

执行 git gc 之后,您会发现 .git 文件夹的大小得到了显著减少。

步骤四:推送到远程仓库(强制推送)

由于您修改了历史记录,现在必须使用强制推送 (–force) 将新的、更小的历史记录覆盖远程仓库。

再次警告: 强制推送会覆盖远程仓库的历史。请确保所有团队成员都知道正在发生历史重写,并在您推送之前停止工作。

git push origin --force --all
git push origin --force --tags

完成推送后,通知所有协作者删除其本地仓库,然后重新克隆新的、精简后的仓库。

总结

通过使用 git filter-repo 重写历史,并配合 git reflog expiregit gc 进行垃圾回收,您可以彻底清理 Git 仓库中残留的大文件,有效解决 .git 文件夹体积过大的问题,并提高仓库的维护效率。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 如何清理 Git 仓库中的大文件残留:彻底释放 .git 文件夹占用的磁盘空间
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址