likes
comments
collection
share

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

作者站长头像
站长
· 阅读数 3

概念

git中有一个特殊的符号引用:HEAD,我们可以成它为头指针。HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。

HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的git命令都是从改变 HEAD 的指向开始的。

HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。

注:如果想看 HEAD 指向,可以通过 cat .git/HEAD 查看, 如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD 查看它的指向

图示

我们来通过图示看一下头指针分离究竟是这样的。

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

我们使用一下命令可使头指针分离

# checkout时不指定具体的分支名,而是指定某一次提交的哈希,如上图的C1
git checkout C1

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

从上图我们可以看到两个主要的变化:

  1. main分支上的*不见了,也就是我们当前的代码版本应不是指向main分支了

  2. 多了一个HEAD指针指向C1这个哈希对应的提交记录。

这就是所谓的头指针分离,通常我们的HEAD指针是执行某一个分支名的,如当HEAD指向了main分支是,main分支就会带上*,而通过上述操作,便将头指针与具体的分支名分离了。

头指针分离的常见用途

  1. 当我们修改了一堆代码之后,想要回去之前的某一些提交,看看之前的代码是如何实现的,此时,我们就可以使用头指针分离,检出目标提交的代码查看,查看完之后再切回原本的分支继续开发即可

  2. 做一些不太确定的尝试工作时,我们可以先基于某一次提交分离头指针出来进行尝试修改,如果最终方案可行,再把代码放到目标分支提交。

相对引用

上面我们都是通过提交记录的哈希值在git中移动指针的,实际工作过程中你不得不使用git log查看目标提交记录的哈希值,并且哈希值在真实的 Git 世界中也会更长(基于 SHA-1,共 40 位)。例如fed2da64c0efc5293610bdd892f82a58e8cbc5d8。但令人欣慰的是,Git 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。因此我可以仅输入fed2 而不是上面的一长串字符。

但是,如果我们使用相对引用的话,让指针在git上移动起来就更加方便了。

使用相对引用的话,你就可以从一个易于记忆的地方(比如 bugFix 分支或 HEAD)开始计算。

相对引用非常给力,这里我介绍两个简单的用法:

  • 使用 ^ 向上移动 1 个提交记录
  • 使用 ~<num> 向上移动多个提交记录,如 ~3

例如下面的图:

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

我们想让头指针移动到C1所在的位置

# 方法一:直接用哈希值切换
git checkout C1
# 方法二:使用相对引用
git checkout HEAD^

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

上面两个命令都可以达到这个效果。那么,有同学可能会问了,感觉还是哈希值简单一点呀。我们不要忘了,这边哈希值C1是我们为了画图简化的,真实的哈希值异常复杂。我们再来看看下面这个:

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

如果想要将头指针依次移动到C2C1C0呢?

# 方法一:哈希值
git checkout C2
git checkout C1
git checkout C0
# 方法二:相对引用
git checkout HEAD^
git checkout HEAD^
git checkout HEAD^

现在是否觉得,相对引用更简单了呢?

可能还有写同学觉得,者还是要使用三次HEAD^才能到达目标点,有没有一次到达的方法呢?当然有

如果你想在提交树中向上移动很多步的话,敲那么多 ^ 貌似也挺烦人的,Git 当然也考虑到了这一点,于是又引入了操作符 ~

该操作符后面可以跟一个数字(可选,不跟数字时与 ^ 相同,向上移动一次),指定向上移动多少次。

还是上面的示例:

git checkout HEAD~3

这样也可以达到头指针移动到当前分支之前3个版本的位置。

我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如:

git branch -f main HEAD~3

上面的命令会将 main 分支强制指向 HEAD 的第 3 级父提交。

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

0009-Git不完全操作指南之本地操作5——头指针分离与相对引用

这样,我们就已经将main分支强制移动到了原来位置的第三级父节点处了。