使用 git 时,经常会碰到以下内容:
HEAD
HEAD^
HEAD~
HEAD~2
这么多的 HEAD
,还有 ^
和 ~
傻傻分不清楚。现在我们就一次性将这些数据理顺。
HEAD 是什么
通常情况下,HEAD 指向当前分支中的最后一个提交(commit)。例外情况下,当直接 checkout 到某个特定提交时,HEAD 就不是指向当前分支中的最后一个提交了。可以想像这是个临时的命名分支。而这个 HEAD 指向这个临时命名分支的最后一个提交。
HEAD 相当于编程中指针的概念,它指向分支的最后一个提交。可参考 (git)[https://git-scm.com/book/en/v2/Git-Internals-Git-References] 官方解释。
^
和 ~
的区别
这两个符号通常跟 HEAD 连在一起,组合成需要回退的版本号。这是一个相对的位置。比如相对于当前HEAD的第三个版本。那么就可以写成 HEAD~3
。
^
英文叫 Caret, 中文没有通用名称,我们暂且叫上箭头。而 ~
英文叫 Tilde,中文我们就叫波浪线吧。
在 git HEAD 后面使用这两个符号时,我们需要遵循如下的规则:
~
通常应该使用这个符号。使用这个符号返回指定数量的版本^
当有合并需要回退时,使用此符号。因为合并的时候会有两个或两个以上的父级(提交)
所以,准确地说:
~
是线性层级的回退^
是树状层级的回退
^
Caret 和 ~
Tilde 的复杂案例
^
上箭头,我们下面来看一个复杂的例子:
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
以上案例摘自 stackoverflow
解释常见的 git HEAD 的含义
最后,我们就可以非常容易的得出以下的 git HEAD 的含义了。
HEAD
: 指的是当前分支中的最后一个提交HEAD~1
:当前提交的前一个提交HEAD~
:是HEAD~1
的缩写形式HEAD~86
:是当前提交的前86个提交- `HEAD~3..HEAD:从前3个提交到当前提交,这是一个区间的表示
如何使用 git HEAD
通过 git checkout
:
git checkout HEAD~1
# checkout到当前提交的上一个提交
通过 git reset
:
git reset HEAD~3
# 回退最后三个提交,并且不会移除你的改变.
关于如何回退 git 提交,可以详细查看文章 (Git 如何撤销(回退)本地提交的 commit)[/post/git-undo-local-commit/]