Git:DETACHED HEAD的概念

Git:DETACHED HEAD的概念。

博客

原帖收藏于IT老兵驿站,传递一个IT老兵在凋零前的光和氧。

前言

git使用的时候,经常会碰到DETACHED HEAD,在此总结一下。

正文

HEAD normally refers to a named branch (e.g. master). Meanwhile, each branch refers to a specific commit. Let’s look at a repo with three commits, one of them tagged, and with branch master checked out:

HEAD是一个指针,指向一个branch

1
2
3
4
5
6
7
	   HEAD (refers to branch 'master')
|
v
a---b---c branch 'master' (refers to commit 'c')
^
|
tag 'v2.0' (refers to commit 'b')

上面是一个常见的例子,三个提交,HEAD指针指向c,往往是这个分支上最后的提交。然后又进行了一次修改和提交,生成了d

1
2
3
4
5
6
7
8
9
$ edit; git add; git commit

HEAD (refers to branch 'master')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')

HEAD指向了d
这个时候我们需要重新检出v2.0版本(这种可能性是很大,经常容易出现的),如下:

1
2
$ git checkout v2.0  # or
$ git checkout master^^

这个“^^”符号需要记忆一下。

1
2
3
4
5
6
7
   HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')

这个时候HEAD指针就指向了b,这就是detached HEAD状态,这意味着HEAD指向了某一个提交了,而不再指向当前分支的最后一个提交了。

然后我们又进行了一次提交,就会变成这样:

1
2
3
4
5
6
7
8
9
10
11
$ edit; git add; git commit

HEAD (refers to commit 'e')
|
v
e
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')

one more time,再来一次:

1
$ edit; git add; git commit
1
2
3
4
5
6
7
8
9
	     HEAD (refers to commit 'f')
|
v
e---f
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')

HEAD指向了f
我们可以做任何正常的git操作,如果你想回到master分支,那么。

1
2
3
4
5
6
7
8
9
$ git checkout master

HEAD (refers to branch 'master')
e---f |
/ v
a---b---c------d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')

HEAD重新指向b
这个时候要意识到没有指针指向f提交,最后ef 都会被常规的Git垃圾回收所删除掉,除非我们创建一个指针,例如:

1
2
3
$ git checkout -b foo   (1)
$ git branch foo (2)
$ git tag foo (3)
  1. 创建了一个新的分支指向f,并且更新了HEAD指针,这样HEAD指针就不再是detached状态了
  2. 简单创建了一个新的分支指向f,这个时候HEAD指针仍然是detached状态。
    3.创建了一个新tag,指向f,这个时候HEAD指针仍然是detached状态。

If we have moved away from commit f, then we must first recover its object name (typically by using git reflog), and then we can create a reference to it. For example, to see the last two commits to which HEAD referred, we can use either of these commands:

如果f已经被移除了,我们首先需要恢复它的对象名,使用git reflog,然后我们创建一个指针指向它。例如,想看到HEAD之前的最后两个提交,我们可以使用下面的命令(二选一):

1
2
$ git reflog -2 HEAD # or
$ git log -g -2 HEAD

总结

这篇总结基本上还是以翻译为主,留了一个问题,就是reflog
这些箭头用MD画起来很痛苦,所见不是所得。