news 2026/1/24 14:48:21

深入理解Git Commit的工作原理:从对象引用到空间优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解Git Commit的工作原理:从对象引用到空间优化

文章目录

    • 一、Git的核心:三种对象及其引用
    • 二、三种对象如何协作?
      • 场景 1:首次提交
      • 场景 2:新增文件并提交
      • 场景 3:删除文件再提交
    • 三、那怎么真正“删掉”大文件?
    • 四、分支(Branch)到底是什么?
    • 五、空间优化的秘密与潜在问题
    • 六、结语

举个例子,有一次我不小心将一个依赖文件夹提交了进去,导致仓库大小暴增到几百MB。我赶紧删除模型并重新提交,但仓库大小并未缩小。这让我意识到,我其实并不真正理解Git是如何工作的。

如果你也有过类似的困惑,那么这篇文章将用5 分钟,带你穿透git commit的表层操作,直击 Git 的核心机制——三种对象与引用系统。看完之后,你会真正理解:为什么删掉文件后仓库体积没变?分支到底是什么?Git 为何如此高效又可靠?
写给在日常开发中,只记住了Git的常用命令,却对底层机制一知半解,像我一样的开发者。


一、Git的核心:三种对象及其引用

Git的核心在于三种不可变对象:committreeblob。这些对象存储在.git/objects目录中,通过哈希值也就是唯一标识相互引用,形成一个高效的版本控制系统。

  • Commit 对象:每次提交代码时创建,记录了变更的快照。它包含提交消息、作者、提交者、父提交(parent),并指向一个 tree 对象。
  • Tree 对象:代表提交时的目录结构,包括文件和子目录。它指向 blob 对象或其他 tree 对象。
  • Blob 对象:存储文件的实际内容,是最底层的对象。一旦创建,blob 永不修改或删除。

这种引用机制避免了重复存储:不变的文件只需引用相同的 blob,新变更才创建新 blob,从而节省空间。


二、三种对象如何协作?

场景 1:首次提交

假设你新建一个项目,创建一个文件text1.txt,内容为:

Hello Git!

然后执行:

gitaddtext1.txtgitcommit-m"commit one"

此时,Git 会做三件事:

  1. 生成一个 Blob 对象

    • 内容:Hello Git!
    • 哈希值:737c...
    • 存储路径:.git/objects/73/7c...
  2. 生成一个 Tree 对象

    • 表示当前目录结构
    • 内容:blob 737c... text1.txt
    • 哈希值:caae...
  3. 生成一个 Commit 对象

    • 指向上述 Tree
    • 包含作者、提交者、时间、提交信息
    • 哈希值:eddf...

你可以用以下命令查看这些对象的内容:

gitcat-file-peddf# 查看 commitgitcat-file-pcaae# 查看 treegitcat-file-p737c# 查看 blob

简单理解:

Blob 存文件内容,Tree 存目录结构,Commit 存“这次快照是谁在什么时候做的”。


场景 2:新增文件并提交

现在你新增text2.txt,内容为New file,并提交:

gitaddtext2.txtgitcommit-m"commit two"

这时:

  • 新增一个 Blob(169d...)存text2.txt
  • 新建一个 Tree,包含两个条目:
    • blob 737c... → text1.txt,复用旧 Blob对象
    • blob 169d... → text2.txt,新建的 Bolb对象
  • 新建一个 Commit,指向新 Tree,并记录 parent 为eddf...

你会发现:text1.txt的内容没有变,所以 Git 直接复用了原来的 Blob 对象,没有重复存储!

这就是 Git节省空间、高效存储的核心秘密。


场景 3:删除文件再提交

接着你删除text2.txt,并提交第三次:

gitrmtext2.txtgitcommit-m"commit three"

新的 Commit 会指向一个只包含text1.txt的 Tree,169d...这个 Blob 依然存在于.git/objects/中!

重要结论
一旦 Blob 被创建,它就永远不会被自动删除——即使你删掉了对应的文件并提交。
因为 Git 的设计哲学是:历史不可篡改,所有对象永久保留(直到被显式清理)

这正是开头那个“文件删不掉”的根本原因:那个几百 MB 的文件已经被转成 Blob 存入 Git 历史,后续提交无法让它消失。


三、那怎么真正“删掉”大文件?

解决方案分两步:

  1. 重写历史,移除包含大文件的那次提交
    比如:git filter-repoBFG Repo-Cleaner
  2. 清理悬空对象
    gitreflog expire--expire=now--allgitgc--prune=now--aggressive

但需注意重写提交历史所带来的影响,比如说团队协作的场景。


四、分支(Branch)到底是什么?

你可能会问:我们天天用的maindev分支去哪儿了?它们也是对象吗?

不是!分支只是一个“指向 Commit 的指针”

.git/refs/heads/目录下,每个分支都是一个文本文件。例如:

cat.git/refs/heads/main# 输出:98ea1234... (即最新 commit 的哈希)

当你执行git checkout main,Git 只是把HEAD指向这个 Commit。
你可以随时让分支指向任意 Commit,甚至删除分支其实只是删掉这个指针,但 Commit 和它的对象依然存在


五、空间优化的秘密与潜在问题

引用机制的核心优势是高效存储。每个 commit 只记录变更,不复制整个仓库。例如,不变的文件共享 blob,新增或修改才生成新 blob。这在大型项目中显著节省空间。

然而,这也带来问题:如开头所述,误提交大文件会创建大量 blob,即使后续删除,blob 也不会自动消失,导致仓库膨胀。

可以试试

  • 使用git resetgit rebase删除包含大文件的 commit,使相关 blob 成为“悬空对象”。
  • 运行git gcgit prune清理悬空对象,真正缩小仓库。
  • 预防措施:使用.gitignore忽略大文件,避免初次提交。

六、结语

Git 依赖 commit、tree 和 blob 的引用链来管理版本历史。这种设计确保了不可变性和效率,但也要求开发者理解其不可逆性。掌握这些基础,下次遇到仓库问题时,你能轻松诊断和修复。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/20 20:26:28

为什么你的Cursor AI总是提示“试用限制“?3个步骤彻底解决

为什么你的Cursor AI总是提示"试用限制"?3个步骤彻底解决 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve rea…

作者头像 李华
网站建设 2026/1/20 16:19:14

腾讯开源Hunyuan-1.8B:Int4量化+256K上下文大模型

导语:腾讯正式开源Hunyuan-1.8B-Instruct-AWQ-Int4大语言模型,通过Int4量化技术与原生256K超长上下文窗口,在保持高性能的同时实现轻量化部署,为边缘设备到企业级系统提供多场景解决方案。 【免费下载链接】Hunyuan-1.8B-Instruct…

作者头像 李华
网站建设 2026/1/24 6:03:20

精通Zotero文献管理:Better BibTeX完整使用指南

精通Zotero文献管理:Better BibTeX完整使用指南 【免费下载链接】zotero-better-bibtex Make Zotero effective for us LaTeX holdouts 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-better-bibtex 在学术写作过程中,Zotero作为一款强大的…

作者头像 李华
网站建设 2026/1/19 19:23:02

3步搞定Waydroid镜像部署:从缓慢下载到极速启动的终极指南

3步搞定Waydroid镜像部署:从缓慢下载到极速启动的终极指南 【免费下载链接】waydroid Waydroid uses a container-based approach to boot a full Android system on a regular GNU/Linux system like Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/wa/waydr…

作者头像 李华
网站建设 2026/1/21 9:26:02

Magistral 1.2:24B多模态模型免费本地部署教程

导语:Mistral AI最新发布的Magistral 1.2模型凭借240亿参数、多模态能力和本地化部署优势,正在重新定义个人与企业级AI应用的边界,普通用户只需单张RTX 4090或32GB内存设备即可体验媲美云端服务的智能交互。 【免费下载链接】Magistral-Small…

作者头像 李华
网站建设 2026/1/21 9:59:42

解密Android OTA:payload-dumper-go实战指南与性能优化

解密Android OTA:payload-dumper-go实战指南与性能优化 【免费下载链接】payload-dumper-go an android OTA payload dumper written in Go 项目地址: https://gitcode.com/gh_mirrors/pa/payload-dumper-go 你是否曾经面对Android系统更新包中的payload.bin…

作者头像 李华