前言

在新建分支的情况下,HEAD如何发生变化。其次,对HEAD的专业字符进行讲解。

HEAD不仅可以指向某一个分支,它还可以指向某一个的commit。

我们现在来创建一个新分支,看看HEAD怎么变化。

git checkout -b xxx yyy:基于分支yyy创建一个新分支xxx并切换到新分支xxx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 G:\mygitea\GitLearn\learn01   master 
$ git branch -av
checkout 5bc7fdf rename test
fix_css 9fa98d6 change background color
* master 5bc7fdf [ahead 2] rename test
temp e1514cf test1
remotes/origin/master b390c28 add modified html css

G:\mygitea\GitLearn\learn01   master 
$ git checkout -b fix_readme fix_css
Switched to a new branch 'fix_readme'

G:\mygitea\GitLearn\learn01   fix_readme 
$ cat .git\HEAD
ref: refs/heads/fix_readme

G:\mygitea\GitLearn\learn01   fix_readme 
$ gitk --all

HEAD不仅仅可以指代新分支的最后一次提交,同时HEAD还可以不和分支挂钩,它处于分离头指针的状态,指向该状态下提交的commit对象上。

当我们做分支切换时,HEAD就会切换到新分支。

HEAD的指代

HEAD要么指向某一个分支要么指向某一个commit。其实实质上分支也是对某一个commit的指定,即最终HEAD指向的都是一个commit。

1
2
3
4
5
6
7
8
9
10
11
 G:\mygitea\GitLearn\learn01   fix_readme 
$ cat .git\HEAD
ref: refs/heads/fix_readme

G:\mygitea\GitLearn\learn01   fix_readme 
$ cat .git\refs\heads\fix_readme
9fa98d6eb27abdf05064e5ced0c4400a6ca847b5

G:\mygitea\GitLearn\learn01   fix_readme 
$ git cat-file -t 9fa98d6eb
commit

HEAD在分支比较中的用法

在分支git diff比较中,我们可以用两个分支的commit id来比较,也可以借由head指代分支来比较:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 G:\mygitea\GitLearn\learn01   fix_readme 
$ git diff 9fa98d6 012ae46
diff --git a/styles/style.css b/styles/style.css
index f6a2094..69dc8a0 100644
--- a/styles/style.css
+++ b/styles/style.css
@@ -1,5 +1,5 @@
body{
- background-color: green;
+ background-color: orange;
font-family: 'Monaco', sans-serif;
color: white;
}

G:\mygitea\GitLearn\learn01   fix_readme 
$ git diff HEAD HEAD~1
diff --git a/styles/style.css b/styles/style.css
index f6a2094..69dc8a0 100644
--- a/styles/style.css
+++ b/styles/style.css
@@ -1,5 +1,5 @@
body{
- background-color: green;
+ background-color: orange;
font-family: 'Monaco', sans-serif;
color: white;
}

在此处,HEAD用于指代当前分支,HEAD~n表示当前分支的前第n个父分支。

其中在Linux中,HEAD^^HEAD^2等同于HEAD~2HEAD~~

总结

1 一个节点,可以包含多个子节点(checkout 出多个分支)
2 一个节点可以有多个父节点(多个分支合并)
3 ^是~都是父节点,区别是跟随数字时候,^2 是第二个父节点,而~2是父节点的父节点
4 ^和~可以组合使用,例如 HEAD~2^2

“^”这个操作符代表父commit。
当一个commit有多个父commit时,可以通过在符号“^”后面跟上一个数字来表示第几个父commit。
比如,”A^” 等于 “A^1”(表示A这个commit的第1个父commit)。
连续的“^”符号依次沿着父commit进行定位,直到某个祖先commit。
~ 相当于连续n个符合“^”。所以,HEAD^^ 等同于 HEAD~2 是对的。还有,这些都可以自己做实验测试一下的。

补充:

git branch -avgit branch -v

加了 -a ,代表也会显示 remote 的分支。 如果一样,说明你没有添加 remote ,也就是只有本地分支。