2023-04-02 05:00:03

Git中的HEAD是什么?

您可以看到Git文档中这样说

分支必须在HEAD中完全合并。

但Git HEAD到底是什么?


当前回答

我认为'HEAD'是当前的检出提交。换句话说,'HEAD'指向当前签出的提交。

如果你刚刚克隆了,没有签出,我不知道它指向什么,可能是一些无效的位置。

其他回答

要把正确答案中的要点讲清楚,一个很好的方法就是跑步 git reflog HEAD,你会得到HEAD所指向的所有地方的历史。

在这些答案中,有一个可能微妙但重要的误解。我想我应该加上我的答案来澄清一下。

什么是HEAD?

头就是你

HEADis a symbolic reference pointing to wherever you are in your commit history. It follows you wherever you go, whatever you do, like a shadow. If you make a commit, HEAD will move. If you checkout something, HEAD will move. Whatever you do, if you have moved somewhere new in your commit history, HEAD has moved along with you. To address one common misconception: you cannot detach yourself from HEAD. That is not what a detached HEAD state is. If you ever find yourself thinking: "oh no, i'm in detached HEAD state! I've lost my HEAD!" Remember, it's your HEAD. HEAD is you. You haven't detached from the HEAD, you and your HEAD have detached from something else.

HEAD可以附着在什么上?

HEAD可以指向提交,但通常不会。让我再说一遍。通常,HEAD并不指向提交。它指向一个分支引用。它被附加到那个分支,当你做某些事情时(例如,提交或重置),附加的分支将随着HEAD一起移动。您可以通过查看引擎盖下面的内容来查看它所指向的内容。

cat .git/HEAD

通常你会得到这样的结果:

ref: refs/heads/master

有时候你会得到这样的结果:

a3c485d9688e3c6bc14b06ca1529f0e78edd3f86

That's what happens when HEAD points directly to a commit. This is called a detached HEAD, because HEAD is pointing to something other than a branch reference. If you make a commit in this state, master, no longer being attached to HEAD, will no longer move along with you. It does not matter where that commit is. You could be on the same commit as your master branch, but if HEAD is pointing to the commit rather than the branch, it is detached and a new commit will not be associated with a branch reference.

如果您尝试下面的练习,您可以图形化地看待这个问题。从git存储库中运行这个。你会得到一些略有不同的东西,但它们的关键部分会在那里。当需要直接签出提交时,只需使用从第一个输出中获得的缩写散列(这里是a3c485d)。

git checkout master
git log --pretty=format:"%h:  %d" -1
# a3c485d:   (HEAD -> master)

git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h:  %d" -1   
# a3c485d:   (HEAD, master)

好的,这里的输出有一个小的差别。直接签出提交(而不是分支)会给我们一个逗号而不是一个箭头。你觉得呢,我们是处于超然的HEAD状态吗?HEAD仍然引用与分支名称相关联的特定修订。我们还在主分支上,不是吗?

现在试一试:

git status
# HEAD detached at a3c485d

没有。我们处于“分离的头部”状态。

你可以用git log -1看到(HEAD -> branch)和(HEAD, branch)的相同表示。

总之

HEAD就是你。无论你在哪里,它都指向你所办理的任何手续。通常这不是一个提交,而是一个分支。如果HEAD确实指向一个提交(或标记),即使它是一个分支也指向的同一个提交(或标记),您(和HEAD)已经从那个分支中分离出来了。由于您没有附加到您的分支,所以当您进行新的提交时,该分支不会跟随您。然而,HEAD会。

分支实际上是一个持有提交ID(例如17a5)的指针。 HEAD是指向用户当前工作的分支的指针。

HEAD有一个如下所示的引用流:

ref:

您可以通过访问您正在工作的存储库中的.git/HEAD .git/refs来检查这些文件。

HEAD几乎字面上就是分支的头。所以当你观察一个分支时,你看到的是最新的提交,也就是这个分支的头。但是,您可以将自己指向该分支历史上更远的另一个提交,当您这样做时,您是在将HEAD移动到前一个提交。由于HEAD自然属于分支中的最新提交,因此它被认为是分离的。

视觉表现。每一根树枝都是一条毛毛虫,每一根树枝都是这个生物的一个部分。因此HEAD将位于最前面的段中。如果您将HEAD从该部分移除到另一个要使用的节段,则您已经将HEAD从自然节段中分离出来。希望你能明白。

现在如果你在主分支中分离HEAD,然后签出newFeature,然后再次签出main, HEAD仍然会被分离,并且是在另一个提交之上。我把HEAD看作一面镜子,你可以把它指向你想要的地方。

我自己还没有弄清楚,但Silfheed对“贴在节点上的便利贴”定义的链接是迄今为止我发现的最好的链接。

我想分享一下我对寻找定义的印象,否则我为什么要把它留给自己。 我把它理解为粘在Git树空间当前位置上的贴纸。我错过了这样一个术语——GIT树中的当前位置,它有自己的属性来指示我们所处的位置。

“参考”或“指针”之类的概念我不太清楚。在我看来,它们暗示了一种新的抽象层次,我们从抽象层次的内部来“指”某物。这可能不是真的,但到目前为止,这是我的看法。