git中的HEAD是什么?


232

上一次提交,HEAD和我在目录中可以看到的文件状态之间似乎有所不同。

什么是HEAD,我该怎么办?应该避免什么错误?



1
使用Git v1.8.4开始,在使用下面所有的答案HEAD或者head现在可以使用@代替HEAD代替。请参阅此答案(最后一部分),以了解为什么可以这样做。

3
From git-scm:Git中的HEAD是指向当前分支引用的指针,而该分支引用又是指向您上一次提交或最后签出到工作目录中的提交的指针。这也意味着它将成为您下一次提交的父项。通常认为它是最简单的,因为HEAD是您最后一次提交的快照。
Quazi Irfan

Answers:


185

HEAD是对当前已检出分支中最后一次提交的引用。


有一个小例外,那就是分离的HEAD。一个分离的头是你,只要你签出在结束了的情况提交,而不是一个分支(或标签)。在这种情况下,您必须将其想象成一个没有名称的临时分支。因此,只有命名头,而不是命名分支引用。它仍然允许您进行提交(这将更新HEAD),因此,如果您将分离的HEAD视为没有名称的临时分支,则上述简短定义仍然适用。


1
那你为什么有两个脑袋呢?
e-satis

1
@ e-satis:有时您会看到称为heads的分支-它们存储在中refs/heads。不过,小写字母与有所不同HEAD。我的回答对此做了澄清。
卡斯卡贝尔

7
@ e-satis:那不是正则表达式。这^只是git的“之前的提交”符号-即当前版本之前的提交。(如果当前是合并,则使用第一个父级。)
Cascabel 2010年

1
@ e-satis:有关指定提交的所有方法的更多信息,请参见git-rev-list手册页的“指定修订版”部分-这只是一小部分。kernel.org/pub/software/scm/git/docs/…–
卡斯卡贝尔

1
不,当rev和HEAD指向同一提交时,没有区别。您甚至可以编写提交ID(SHA-1值)而不是rev​​或HEAD。不用担心,您不会在问题上骚扰我们:)(至少我:P)

87

HEAD 是对当前已检出提交的引用(引用)。

在正常状态下,它实际上是对已签出分支的符号引用-如果查看.git / HEAD的内容,则会看到类似“ ref:refs / heads / master”的内容。分支本身是对分支顶端的提交的引用。因此,在正常状态下,HEAD有效地指的是当前分支末端的提交。

也可能有“分离头”。当您检出(本地)分支以外的其他内容(例如远程分支,特定的提交或标签)时,会发生这种情况。选择交互式提交时,最常见的查看方法是在交互式变基过程中。在分离的HEAD状态下,您的HEAD是对提交的直接引用-.git / HEAD的内容将是SHA1哈希。

一般来说,HEAD只是一个方便的名称,意为“您已检出的内容”,而您实际上不必为此担心。只要知道您已签出的内容,并记住如果您不在分支上(分离的HEAD状态),可能就不想提交,除非您知道自己在做什么(例如,处于交互式rebase中) 。


6
这是我不明白的事情。如果签出远程分支,为什么最终会出现“分离的HEAD”。您为什么不自动跳入本地仓库中与您的遥控器相对应的分支?
e-satis

3
@ e-satis:如果要本地分支,请签出本地分支。请记住,两者不一定相同-您必须告诉本地的一个合并远程的一个(或拉)。跟踪只是为了让它知道在您询问时自动拉哪个。分离的原因是,远程分支旨在成为指向远程回购中分支最后看到的位置的指针。如果您尝试提交,则远程仓库不会更改,因此远程分支也不应更改。
卡斯卡贝尔

1
好的,那是我没有得到的:拥有以某种方式命名的本地分支并不意味着它与远程分支相同。一开始真的很难,因为我来自SVN背景:-)谢谢你。顺便说一句,如何将无头HEAD移动到本地分支以在此处提交?
e-satis

3
@ e-satis:总体答案是git rebase <branch> HEAD。这将找到的最后一个共同祖先<branch>HEAD,然后采取所有提交从那里HEAD并应用它们(变基他们)到<branch>。它实质上是通过将它们作为补丁应用来完成的,因此,如果两个分支确实不同,则可能会发生冲突。但是,如果<branch>是的祖先HEAD(即您来对地方了,只是忘记了您已经与众不同HEAD),则重新设置基准只是一次快速合并。
卡斯卡贝尔

3
经过一段时间的搜索,这是我所见过的最清晰,最准确的git HEAD描述之一。
LarsH '16

21

我一直认为这HEAD~5意味着GO之前要提交5次。但是它不包含命令的GO部分。它仅包含命令的引用/“在何处” 部分

在外行人而言它用来回答的问题:在哪里我应该去?向哪个提交?

  • HEAD 表示(对当前提交的引用)
  • HEAD~1 意味着(对)1个提交之前的提交
  • HEAD~ ALSO表示(引用)1个提交之前
  • HEAD~87 意味着(对)87之前的提交

用法:

  • git checkout HEAD~1 实际将GO / checkout到1 commit / reference之前
  • git reset HEAD~3 将取消提交您最近的3次提交-不删除更改,即您可以一起查看最近3次提交中所做的所有更改,删除不喜欢的内容或添加到其中,然后再次提交所有内容。
  • git reset --hard HEAD~3取消提交您的上一次提交并删除其更改。它将完全删除那些更改。有关更多信息,请参见此处
  • git diff HEAD~3 用于检查最近3次提交中的更改

3
回到我自己的答案:)
亲爱的,

15

Git中的HEAD指针

Git维护一个称为HEAD的引用变量。我们将此变量称为指针,因为它的目的是引用或指向存储库中的特定提交。当我们进行新的提交时,指针将改变或移动以指向新的提交。HEAD始终指向我们存储库中当前分支的尖端。现在,这与我们的存储库有关,而与暂存索引或工作目录无关。

另一种思考方式是存储库的最后状态或上次检出的状态,并且因为它是存储库的退出状态或最后状态,所以您也可以说HEAD指向下一个提交的父目录,或者它是提交写作的地方。

我认为可以考虑的一个很好的比喻是盒式磁带录音机上的播放和记录磁头。当我们开始录制音频时,磁带会越过磁头,然后录制到磁头上。当我们按下Stop时,记录头停止的地方是第二次按下Record时它将再次开始记录的地方。现在我们可以四处移动,可以将磁头移动到其他位置,但是无论磁头位于何处当我们再次点击“录制”时,它将开始录制。

Git中的HEAD指针非常相似,它指向我们接下来要开始记录的地方。在这里,我们将已提交的内容留在存储库中。


0

简单来说,HEAD是对当前签出分支中最后一次提交的引用。

将HEAD视为“当前分支”。当您使用git checkout切换分支时,HEAD版本将更改为指向新分支的尖端。

您可以通过执行以下操作查看HEAD指向的内容:

cat .git/HEAD

HEAD可能引用与分支名称不相关的特定修订版。这种情况称为分离的HEAD。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.