Git 的核心心智模型
理解 Git 不应该从命令(add/commit)开始,而应该从它的数据流向和存储原理开始。
一、Git 的三个工作区域
Git 将代码的存在状态划分为三个主要的逻辑区域,你可以把它们看作是一个“三阶跳板”:
1. 工作区 (Working Directory)
你在电脑上能直接看到的、正在编辑的文件目录。
- 状态:这是“活”的代码。
- 操作:你在这里写 Bug、修 Bug、重构。
2. 暂存区 (Staging Area / Index)
一个中转站。当你执行 git add 时,改动会进入这里。
- 作用:它记录了你下一次提交要包含的内容。
- 价值:允许你精细化控制提交。比如你改了 10 个文件,但只想把其中 3 个相关的逻辑作为一个 commit 提交,就可以只
add这 3 个。
3. 本地仓库 (Local Repository / .git directory)
当你执行 git commit 时,暂存区的内容会被永久存入这里。
- 核心:这里存储的是完整的版本历史。一旦进入这里,只要你不去删
.git文件夹,你的代码几乎就是安全的。
二、Git 的底层哲学:快照 vs 差异
Git 与其他版本控制系统(如 SVN)最大的区别在于它如何存储数据。
传统系统(如 SVN):基于差异 (Delta-based)
它存储的是文件的变化量。
- 它记录第 1 版到第 2 版之间哪几行改了。
- 优点:理论上省空间(如果改动很小)。
- 缺点:回溯历史时需要根据基础版本叠加一堆差异,速度较慢。
Git:基于快照 (Snapshot-based)
每次提交时,Git 都会对当前所有文件“照张相”。
- 如果文件变了:Git 存储该文件的新版本。
- 如果文件没变:Git 不会重复保存,而是直接指向之前的旧文件(通过指针/索引)。
为什么这很重要?
因为这种“快照”机制让 Git 在切换分支、查看历史版本时快得惊人。它不需要去计算差异,只需要切换一下指针指向哪张“照片”即可。
三、总结:Git 的数据流向
- 修改文件 -> 发生在 工作区。
git add-> 将修改从工作区同步到 暂存区。git commit-> 将暂存区的快照永久存入 本地仓库。
理解了这三个区域和快照机制,你就掌握了 Git “时空管理”的钥匙。
四、核心原理:Git 是如何存储数据的
要彻底理解 Git 的“快照”是如何工作的,需要知道 Git 本质上是一个按内容寻址的文件系统。
1. SHA-1 哈希值:数据的身份证
Git 使用 SHA-1 哈希算法对所有存储的内容生成一个 40 位的十六进制字符串。
- 唯一性:内容变了,哈希值就变了。
- 去重:如果两个文件的内容完全相同,它们会共用同一个哈希值,Git 只存储一份数据。这就是为什么 Git 的“快照”比想象中更省空间。
2. Git 的三种核心对象
Git 的仓库里主要存着三种对象:
- Blob (Binary Large Object):只存储文件内容。它不关心文件名,只关心内容。
- Tree (树对象):存储目录结构。它记录了文件名、文件权限,以及指向对应 Blob 或子 Tree 的指针(哈希值)。
- Commit (提交对象):存储版本信息。它包含指向顶层 Tree 的指针(当前快照)、作者、日期、提交说明,以及指向上一次提交(Parent Commit)的指针。
3. 分支:一个轻量级的指针
在 Git 中,分支(Branch)既不是文件夹,也不是文件的副本。
- 本质:分支仅仅是一个指向某个 Commit 对象的可变指针。
- 切换分支:当你执行
git checkout或git switch时,Git 只是让HEAD指针指向不同的分支名,并根据该分支指向的 Commit 快照更新你的工作区。 - 效率:这就是为什么在 Git 里创建和切换分支快如闪电的原因——你只是在改几个字节的指针值。
五、总结:如何高效使用 Git
理解了这些原理,你会发现:
git add是在计算哈希值并创建 Blob 对象。git commit是在创建 Tree 和 Commit 对象,并移动当前分支指针。git reset是在强行移动分支指针。
理解了这些,你就从“命令使用者”进阶到了“原理掌握者”。