2023-04-02 05:00:03

Git中的HEAD是什么?

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

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

但Git 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会。

其他回答

这两个可能会让你困惑:

head

指向分支最近提交的命名引用。除非使用包引用,否则头文件通常存储在$ GIT_DIR/refs/heads/中。

HEAD

当前分支,或者您的工作树通常是从HEAD所指向的树生成的。HEAD必须指向一个头,除非你正在使用一个独立的头。

假设这不是一种叫做“分离HEAD”的特殊情况,那么,正如O'Reilly Git书第2版第69页所述,HEAD的意思是:

HEAD总是指当前节点上最近的提交 分支。当您更改分支时,HEAD将被更新为引用新的分支 布兰奇的最新提交。

so

HEAD是当前分支的“尖端”。

注意,我们可以使用HEAD表示最近的提交,使用HEAD~表示提示之前的提交,使用HEAD~~或HEAD~2表示更早的提交,以此类推。

感觉HEAD只是您签出的最后一次提交的标记。

这可以是一个特定分支的顶端(例如“master”),也可以是某个分支的中间提交(“detached head”)。

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

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

HEAD指的是工作副本所指向的当前提交,即当前签出的提交。从官方Linux内核文档中指定Git修订:

HEAD命名您在工作树中基于更改的提交。

但是请注意,在即将到来的Git 1.8.4版本中,@也可以用作HEAD的简写,Git贡献者Junio C Hamano在他的Git Blame博客中指出:

你可以不说“HEAD”,而说“@”。“git log @”。

Stack Overflow用户VonC在回答另一个问题时还发现了一些有趣的信息,关于为什么选择@作为简写。

同样值得注意的是,在某些环境中,没有必要将HEAD大写,特别是在使用不区分大小写文件系统的操作系统中,特别是Windows和OS X。