2023-04-02 05:00:03

Git中的HEAD是什么?

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

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

但Git HEAD到底是什么?


当前回答

看看http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is

图3 - 5。HEAD文件指向你所在的分支。

其他回答

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

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

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

您可以将HEAD视为“当前分支”。当您使用git签出切换分支时,HEAD修订将更改为指向新分支的尖端。

你可以通过这样做来查看HEAD指向什么:

cat .git/HEAD

在我的例子中,输出是:

$ cat .git/HEAD
ref: refs/heads/master

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。

Git都是关于提交的。 Head指向当前签出的提交。

$ git cat-file -t HEAD
commit

无论何时签出一个分支,HEAD都指向该分支上的最新提交。HEAD的内容可检查如下(主分支):

$ cat .git/refs/heads/master
  b089141cc8a7d89d606b2f7c15bfdc48640a8e25

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

什么是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会。