我从git init第一天入坑Git,一开始最绕不过去的坎就是分支。当时网上教程铺天盖地都是"创建分支、合并分支、删除分支"的操作命令,照着敲确实能跑通,但一旦遇到冲突、回滚、reset这些场景,整个人就懵了。直到后来我把迁移到.git目录里盯着文件看了几天,才真正琢磨明白一个事儿:Git的分支,本质上就是一个个指针。这个认知一旦建立起来,之前那些乱七八糟的命令全都能串成一条线。
这篇文章我打算把"Git分支是指针"这件事掰开揉碎讲清楚,从Git底层对象存储讲到HEAD、分支名、标签这三类引用的协作方式,再带你走一遍从创建分支到合并删除的完整流程,最后把我这些年踩过的和指针、分支相关的坑全部倒出来。如果你是刚开始学Git,或者已经用了一段时间但总觉得哪里没想通,这篇文章应该正好帮你补上那块关键的拼图。
1. 分支的本质:一支可移动的指针
先把结论放在最前面:Git里的分支,不是文件夹,也不是代码的分区,它只是一个指向某个提交(commit)的可移动指针。这句话说起来简单,但理解它需要你先搞清楚Git仓库里的数据到底是什么样的存在。
1.1 Git仓库底层到底存的什么东西
我们平时看到的代码文件,在Git眼里其实是三类对象:blob(文件内容对象)、tree(目录树对象)、commit(提交对象)。你每次执行git add和git commit,Git会把你工作区的文件内容生成blob对象,按目录结构生成tree对象,再生成的commit对象把两者串起来,同时记录提交的父提交、作者、时间等信息。
这里的关键点在于:每个对象都有一个用SHA-1算法计算出来的40位十六进制哈希值作为地址。对象之间通过哈希值互相引用,commit引用tree,tree引用blob和子tree,形成了版本数据的完整链条。
我在实践中特别喜欢用git cat-file -p <commit哈希>这个命令去看一个commit里到底装了什么。比如你拿到一个提交哈希,执行git cat-file -p HEAD,能看到类似这样的输出:
bash复制tree 2b8a4f1a3d9c5e7d2f4b8a0c1d3e5f7a9b0c2d4e
parent a3f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a
author ZhangSan <zhangsan@example.com> 1699999999 +0800
committer ZhangSan <zhangsan@example.com> 1699999999 +0800
修复了登录模块的空指针问题
看到没有,commit对象里有一行parent,指向它的父提交。这条父子链一直往上追溯,就能到达仓库的根提交。换句话说,Git的版本历史本质上是一条由commit对象组成的单向链表,每个commit都带着自己内容的完整快照(通过tree对象)。
这就是为什么Git切换分支那么快的原因了——它不是在复制文件,只是在改变当前指针的指向。这也是很多初学者最容易产生误解的地方:总以为分支就是代码的副本,怕切来切去把代码搞丢了,其实完全不用担心,你的每份提交都安安稳稳躺在.git/objects里。
1.2 分支名和commit哈希之间的那层映射
现在我们把视角拉升到更上层。既然每个提交都有哈希地址,那么一个分支又是怎么和这些哈希关联起来的呢?答案在.git/refs目录下。
随便打开一个Git仓库,执行find .git/refs -type f,正常情况下可以看到:
bash复制.git/refs/heads/master
.git/refs/remotes/origin/master
用cat .git/refs/heads/master,输出的就是当前master分支所指向的那个commit哈希。就这么简单,分支的本质就是一个文件,文件里存一个40位的哈希值。这个哈希值会随着你不断提交而自动更新,所以我说它是一支"可移动的指针"。
再进一步,Git还维护了一个特殊的引用叫HEAD,它通常指向refs/heads/master这样的分支名,而HEAD文件本身存放在.git/HEAD里。你可以看一眼:
bash复制cat .git/HEAD
# 输出: ref: refs/heads/master
当你执行git checkout dev切到dev分支后,.git/HEAD的内容就会变成ref: refs/heads/dev。所以整个过程简单得让人发指:切换分支,改的就是HEAD这个"指针的指针"所指向的目标。
从信息结构上看,Git仓库里的指针关系可以整理成一句话:HEAD指向某个分支名,分支名指向某个commit哈希,commit哈希通过parent字段指向上一代commit,如此层层回溯,最终形成整条版本链。理解了这个链条,后面所有分支操作就都有了底层依据。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 三类核心指针:分支引用、HEAD、标签
在我们真正去操作分支之前,有必要分清Git仓库里常见的三指针系统。很多人搞不懂ta
