1.7. 审视 Git 的分支描述

未匹配的标注

通过前面对 commit, tree, blob, tag 这四种对象的审视,我们现在对 git cat-file 这个命令已经有了一个比较充分的认识。现在是时候探索一下 git 分支的表示了。

使用 -t 这个短标识。我们可以看到 git 的分支是哪种对象。

➜  plumbing-demo git:(main) git cat-file -t main
commit

没错,一个分支就是对一个 commit 对象的引用。这就是说我们可以用一个普通的 git cat-file commit 这个命令来检查分支。

➜  plumbing-demo git:(main) git cat-file commit main
tree 69d1223f517e74c307a6e34489c87e4c53156197
parent c2645af2b5ab003896c10c1e77203b7d91a036ff
author hustnzj hustnzj@example.com 1663660827 +0800
committer hustnzj hustnzj@example.com 1663661674 +0800

update .gitignore

输出跟我们原来使用 git cat-file commit HEAD 一样的结果。这说明:main 分支和 HEAD 都是都仅仅是对一个 commit 对象的引用。

使用文本编辑器打开 .git/refs/heads/main 这个文件,可以看到里面有一个 commit 的校验和,它是最近一个 commit 的校验和。

➜  plumbing-demo git:(main) cat .git/refs/heads/main
8f809e04a436df0fccab26ac40cdfc8b32d6ee3d 

使用 git log -n 1来确认:

➜  plumbing-demo git:(main) git log -n 1
# 8f809e04a436df0fccab26ac40cdfc8b32d6ee3d

.git/refs/heads/main这个文件就是 Git 维护 main 分支所需的一切,所有其他的信息都可以通过上一节讨论的那个 commit 对象的关系图来提取出来。

另一方面,HEAD 的引用是保存在 .git/HEAD 里面。 HEAD不像分支头,不是一个到 commit 的直接的链接。相反它引用的是一个分支。这个分支是 git 用来确定当前检出的是哪一个commit。

➜  plumbing-demo git:(main) cat .git/HEAD
ref: refs/heads/main

这说明当前的这个 HEAD 指向的是 main 分支。而我们最开始前面看的 main 分支这个文件refs/heads/main它里面包含的是最近一个 commit 里面的校验和。

当 HEAD 与任何分支的头都不吻合的时候,它就是 detach 的状态。在这个时候, .git/HEAD 里面包括的就不是一个分支了。

比如我们运行 git checkout HEAD~1,这个命令就是检出当前 commit 的前一个,然后就可以看到我们现在处于的是 detach head 的状态。

这个时候我们去看 .git/HEAD 里面包括了什么,它里面包括的就不再是一个 branch 的引用,而是直接是一个 commit,就是我们 check out 的这个 commit。

➜  plumbing-demo git:(c2645af) cat .git/HEAD
c2645af2b5ab003896c10c1e77203b7d91a036ff

从上面就可以知道,不管你是不是在 detach 的状态, git checkout 这个命令 总是将检出的引用记录在 .git/HEAD 里面。如果是在分支状态,这个时候 .git/HEAD 里面记录的就是一个分支文件的引用。如果是在 detach head 状态,.git/HEAD 里面记录的就是一个 commit 校验和。

现在让我们返回 main 分支 git checkout main.

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~