Git代码库大文件历史记录的清理方法

 更新时间:2025年11月24日 08:43:51   作者:hen3y  
在日常开发中,我们可能会不小心将一些大文件(如二进制文件、大型资源文件等)提交到Git仓库中,即使后来删除了这些文件,它们依然存在于 Git 的历史记录中,导致 .git 目录变得非常庞大,本文将介绍如何分析 Git 仓库的占用情况,并使用工具清理历史记录中的大文件

引言

在日常开发中,我们可能会不小心将一些大文件(如二进制文件、大型资源文件等)提交到 Git 仓库中。即使后来删除了这些文件,它们依然存在于 Git 的历史记录中,导致 .git 目录变得非常庞大,严重影响 git clonegit pull 的速度。

本文将介绍如何分析 Git 仓库的占用情况,并使用工具清理历史记录中的大文件。

问题分析

Git 仓库体积过大的主要原因通常是 .git/objects/pack/*.pack 文件过大。Git 将文件历史记录存储在本地的 "database" 中,如果历史记录中包含了大量的二进制文件变动,pack 文件就会迅速膨胀。

[!info] Git Internals - Packfiles Git 使用 packfile 来优化存储。详情可参考:Git - Internals - Packfiles

第一步:找出大文件

在清理之前,我们需要先找出是哪些文件占用了大量空间。

1. 查看仓库大小

使用 git count-objects 命令可以查看仓库的打包对象数量和磁盘占用情况:

# -v: verbose, 显示详细信息
# -H: human-readable, 以人类可读的格式显示大小
git count-objects -v -H

2. 查找 Packfile 中最大的对象

我们可以通过 git verify-pack 命令查看 packfile 中的对象详情,并按大小排序找出最大的几个 blob 对象:

# 查看 .git/objects/pack/ 下的 .idx 文件
# sort -rn -k 3: 按第3列(size)倒序排列
# head -10: 取前10个
git verify-pack -v .git/objects/pack/*.idx | sort -rn -k 3 | head -10

输出结果格式如下:

# SHA-1 (Blob ID) | type | size | size-in-packfile | offset-in-packfile
9704d6e7c732b07418ffe2c0dd2c2030d0cd5a2e blob   2621847 2622645 235218
2bdb752d86091c343f2f4d3af88f038f6b4c2846 blob   2212925 868876 2918139
...

3. 定位具体文件路径

拿到 Blob ID 后,我们需要知道它对应的是哪个文件。使用 git rev-list 配合 grep 可以查找对应的文件名:

# 替换 <blob id> 为上面查到的 SHA-1
git rev-list --objects --all | grep 2bdb752d86091c343f2f4d3af88f038f6b4c2846

输出示例:

2bdb752d86091c343f2f4d3af88f038f6b4c2846 .yarn/cache/playwright-core-npm-1.55.0-1c6d3fab0f-843376a8e2.zip

这样我们就找到了罪魁祸首,例如上面的 yarn/cache/playwright-core-npm-1.55.0-1c6d3fab0f-843376a8e2.zip

第二步:分析问题

通过上面的步骤,我们发现 .yarn/cache/ 目录下的 zip 文件占用了大量空间。

原因分析: 在使用 Yarn 2+ (Berry) 版本时,默认会将依赖以 zip 形式存储。如果项目没有正确配置 .gitignore,或者开发者误操作,就容易将 .yarn/cache 目录提交到 Git 仓库中。这些二进制缓存文件不仅体积大,而且变动频繁,是导致 Git 仓库膨胀的常见原因。

Yarn 2+ 的 .gitignore 最佳实践

根据 Yarn 官方文档,对于大多数非 Zero-Installs 的项目,我们应该忽略以下目录:

# Yarn 2+
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# 关键:忽略缓存目录
.yarn/cache

# 忽略构建状态和安装状态
.yarn/build-state.yml
.yarn/install-state.gz

# PnP 相关
.pnp.*

既然找到了问题根源是误提交了 .yarn/cache,接下来的目标就是将其从历史记录中彻底清除。

第三步:清理大文件

找到大文件后,我们需要将其从所有历史记录中彻底移除。这里推荐使用 BFG Repo-Cleaner,它比原生的 git filter-branch 更快、更简单。

使用 BFG Repo-Cleaner

[!info] BFG Repo-Cleaner BFG 是一个用 Scala 编写的工具,专门用于快速清理 Git 仓库中的大文件或隐私信息。 官网:https://rtyley.github.io/bfg-repo-cleaner/

1. 下载并运行

BFG 提供了一个 .jar 包,需要安装 Java 环境运行。

# 下载 bfg-1.14.0.jar 后,在仓库目录的上一级运行
# my-repo 为你的仓库目录名称

# 方式一:移除超过指定大小的文件 (例如 1M)
java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 1M my-repo

# 方式二:移除指定名称的文件 (支持 glob 模式)
java -jar bfg-1.14.0.jar --delete-files '*.{zip,jar,exe}' my-repo

# 方式三:移除指定文件夹
java -jar bfg-1.14.0.jar --delete-folders '.svn' my-repo

常用参数说明:

  • -b, --strip-blobs-bigger-than <size>: 移除超过指定大小的 blob。
  • -B, --strip-biggest-blobs NUM: 移除最大的前 NUM 个 blob。
  • -D, --delete-files <glob>: 按文件名移除文件。
  • --delete-folders <glob>: 按文件夹名移除文件夹。
  • --no-blob-protection: 允许修改最新提交(默认情况下 BFG 会保护最新的一次 commit 不被修改,以防误删)。

这里我们使用命令删除 .yarn/cache 目录下的所有文件:

java -jar bfg-1.14.0.jar --delete-folders '.yarn/cache' my-repo

2. 物理删除与垃圾回收

BFG 只是更新了 Git 的引用(refs)和历史记录,并没有真正物理删除磁盘上的对象。我们需要运行 Git 的垃圾回收命令来彻底释放空间:

# 强制过期所有 reflog,并执行垃圾回收
git reflog expire --expire=now --all && git gc --prune=now --aggressive

执行完上述步骤后,再次检查仓库大小,应该会发现体积明显减小。最后,需要强制推送到远程仓库:

git push origin --force --all

[!warning] 警告 这是一个破坏性操作,会重写 Git 历史。在执行之前,请务必备份你的仓库! 此外,强制推送后,其他协作者需要重新 clone 仓库或进行 rebase 操作。

到此这篇关于Git代码库大文件历史记录的清理方法的文章就介绍到这了,更多相关Git大文件历史记录清理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Git进行版本控制的实践分享

    使用Git进行版本控制的实践分享

    Git 是目前最流行的分布式版本控制系统,广泛应用于前端开发,Git的强大功能让开发者能够有效管理代码、协作开发、追踪代码变更和版本发布,在本文中,我们将探讨前端开发者在使用 Git 进行版本控制时应遵循的一些最佳实践,需要的朋友可以参考下
    2024-10-10
  • git下实现快速提交及推送

    git下实现快速提交及推送

    本文介绍了多种提高Git效率的方法,包括简化提交信息、简化分支操作、快速暂存、一键提交推送、跳过暂存区、优化网络传输、使用GUI工具、避免大型提交、定期清理Git仓库和使用快速提交工具,这些方法有助于提高开发效率和代码管理质量
    2026-05-05
  • 命令行下的2款网页截图工具推荐

    命令行下的2款网页截图工具推荐

    这篇文章主要介绍了命令行下的2款网页截图工具推荐,分别是针对IE浏览器的IECapt和针对Firefox浏览器的PageSaver,需要的朋友可以参考下
    2014-07-07
  • git branch如何delete方式

    git branch如何delete方式

    文章介绍了如何在Git中删除本地和远程分支,包括删除未合并分支的注意事项,以及如何批量删除已合并分支,还提到了一些常见问题的解决方法和操作总结
    2025-12-12
  • php asp.net 比较 [推荐]

    php asp.net 比较 [推荐]

    如今当提到 Web 开发时,您有许多选择。这些方法中许多都涉及到预处理 - 即,利用特定的标记将代码嵌入到 HTML 页面中
    2009-06-06
  • Git仓库瘦身之彻底清理历史大文件与冗余目录的实战指南

    Git仓库瘦身之彻底清理历史大文件与冗余目录的实战指南

    在日常开发中,Git 仓库常会因误提交图片、二进制库、资源文件等变得臃肿,导致克隆、拉取速度缓慢,本文结合实际场景,分享一套完整的仓库瘦身方案,需要的朋友可以参考下
    2026-01-01
  • Chrome浏览器断点调试技巧(非常详细!)

    Chrome浏览器断点调试技巧(非常详细!)

    在我们日常开发中,常常利用chrome强大的控制台Sources下面进行代码断点调试,这篇文章主要给大家介绍了关于Chrome浏览器断点调试技巧的相关资料,需要的朋友可以参考下
    2023-09-09
  • vscode使用git的配置教程

    vscode使用git的配置教程

    在vscode中使用Git可以帮助我们更方便地管理代码,进行版本控制,下面通过本文给大家介绍vscode使用git的配置教程,感兴趣的朋友一起看看吧
    2024-08-08
  • 微信小程序版的知乎日报开发实例

    微信小程序版的知乎日报开发实例

    相信大家最近都被小程序刷了屏,于是趁周末赶紧撸了个小程序版的知乎日报压压惊, 这篇文章主要是总结一下这个开发体验,和踩过的坑。有需要的朋友们可以参考借鉴。
    2016-09-09
  • 将Sublime Text 设置成中文版的完整教程

    将Sublime Text 设置成中文版的完整教程

    这篇文章主要介绍了将Sublime Text 设置成中文版的完整教程,需要自己添加之后才会有这一项,对Sublime Text中文版设置方法感兴趣的朋友一起看看吧
    2022-01-01

最新评论