【Git 内部】.git 目录全景:三棵树与仓库布局

💡 原文中文,约4200字,阅读约需10分钟。
📝

内容提要

本文介绍了Git的内部结构,重点讲解了.git目录的布局及其组成部分的功能。澄清了常见误区,如Git保存的是内容寻址对象而非文件差异,分支是指向commit的引用。通过实测展示了非bare和bare仓库的区别,以及工作区、索引和HEAD的关系,帮助理解Git的版本管理机制。

🎯

关键要点

  • Git 的核心持久化单元是内容寻址对象(blob、tree、commit、tag),而非文件差异。

  • 分支是指向 commit 的引用,而不是目录里的副本。

  • 没有 refs,无法知道 commit 的名字;没有 index,无法高效暂存;没有 logs,就没有 reflog。

  • 执行 git init 后,.git 目录内的文件包括 HEAD、config、description 等,尚未有 objects/ 和 refs/。

  • 一次提交后,.git 目录新增对象库、分支指向的 commit、reflog 和暂存区等关键路径。

  • 工作区、索引和 HEAD 之间的关系通过 git add、commit 和 checkout 操作进行数据流动。

  • bare 仓库没有工作区和索引,但与非 bare 仓库的对象和引用语义一致。

  • 大量小文件会对存储造成压力,Git 通过 git gc/repack 将松散对象打包以缓解这一问题。

🔎

延伸解读

理解 Git 的核心概念

Git 的核心持久化单元是内容寻址对象,包括 blob、tree、commit 和 tag,而不是文件的差异。这一理解有助于开发者更好地掌握版本控制的本质,避免误解 Git 的工作机制。

bare 与 non-bare 仓库的区别

bare 仓库没有工作区和索引,适合用于服务器端的版本管理,而 non-bare 仓库则包含工作区,适合本地开发。了解这两者的区别可以帮助开发者选择合适的仓库类型以满足不同的需求。

小文件问题的影响

大量小文件会对 Git 的存储造成压力,导致性能下降。Git 提供了 git gc 和 git repack 命令来优化存储,开发者应定期使用这些命令以保持仓库的高效运行。

延伸问答

Git 的核心持久化单元是什么?

Git 的核心持久化单元是内容寻址对象,包括 blob、tree、commit 和 tag。

分支在 Git 中是如何定义的?

在 Git 中,分支是指向 commit 的引用,而不是目录里的副本。

执行 git init 后 .git 目录内会有哪些文件?

执行 git init 后,.git 目录内会有 HEAD、config、description 等文件,但尚未有 objects/ 和 refs/。

bare 仓库与非 bare 仓库有什么区别?

bare 仓库没有工作区和索引,但与非 bare 仓库的对象和引用语义一致。

Git 如何处理大量小文件的问题?

Git 通过 git gc/repack 将松散对象打包,以缓解大量小文件对存储的压力。

工作区、索引和 HEAD 之间的关系是什么?

工作区、索引和 HEAD 之间的关系通过 git add、commit 和 checkout 操作进行数据流动。

🏷️

标签

➡️

继续阅读