Git中的HEAD是什么?

你可以看到Git的文档中有这样的说法

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

但是Git HEAD到底是什么?

您可以将HEAD视为“当前分支”。 当你使用git checkout切换分支时,HEAD版本会改变为指向新分支的顶端。

你可以看看HEAD指出的是:

 cat .git/HEAD 

在我的情况下,输出是:

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

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

引用其他人 :

头只是对提交对象的引用。 每个头都有一个名称(分支名称或标签名称等)。 默认情况下,每个存储库中都有一个名为master的头。 存储库可以包含任意数量的头。 在任何时候,一个头被选为“当前头”,这头是别名头,总是在首都“。

注意这个区别:“头”(小写)是指存储库中任何一个指定的头; “HEAD”(大写)专指当前活动的头部。 这个区别在Git文档中经常使用。

可以在这里find快速覆盖git的内部工作原理的另一个很好的源代码(因此可以更好地理解头部/头部)。 引用(ref :)或者头或者分支可以被认为是粘在提交历史中的提交上的便签纸。 通常他们指向一系列提交的提示,但可以用git checkoutgit revert等来移动它们。

我推荐这个定义,因为它是由github开发者(Scott Chacon)提供的。

整个video将对整个git系统给出一个公平的介绍,所以如果有时间的话,我也build议你观看一下。

希望它会帮助你。

如果你创build一个新的分支会发生什么? 那么,这样做会创build一个新的指针,让你四处走动。 假设您创build了一个名为testing的新分支。 你用git分支命令来做到这一点:$ git branch testing

这会在您当前提交的同一个提交中创build一个新的指针

在这里输入图像描述

Git如何知道你现在在哪个分支? 它保留了一个叫做HEAD的特殊指针。 请注意,这与您可能习惯的其他VCS(如Subversion或CVS)中HEAD的概念有很大不同。 在Git中,这是一个指向当前分支的指针。 在这种情况下,你仍然是主人。 git分支命令只创build了一个新的分支 – 它没有切换到那个分支

在这里输入图像描述

HEAD文件指向你正在的分支。

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

HEAD始终引用当前分支上最近的提交。 更改分支时, HEAD更新为引用新分支的最新提交。

所以

HEAD当前分支的“尖端”

请注意,我们可以使用HEAD引用最近的提交,并使用HEAD~作为提示之前的提交, HEAD~~HEAD~2甚至更早提交,依此类推。

HEAD指的是您的工作副本指向的当前提交,即您当前已经签出的提交。 有关指定Git修订版的官方Linux Kernel文档 :

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

不过要注意的是,在即将到来的Git 1.8.4版本中, @也可以用作HEAD的简写,正如Git贡献者Junio C Hamano在其Git Blame博客中所指出的那样 :

而不是input“HEAD”,你可以用“@”来代替,例如“git log @”。

堆栈溢出用户VonC还发现了一些有趣的信息,为什么@被选为另一个问题的答案的简写 。

另外感兴趣的是,在一些环境中,没有必要使HEAD大写,特别是在使用不区分大小写的文件系统的操作系统,特别是Windows和OS X中。

看看创build和使用分支机构

HEAD实际上是一个文件,其内容决定HEADvariables引用的位置:

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

在这个仓库中,HEAD文件的内容引用了第二个名为refs / heads / master的文件 。 文件refs / heads / master包含主分支上最近提交的散列。

结果是HEAD指向来自.git / refs / heads / master文件的主分支提交。

在这里输入图像描述

我只想在Greg Hewgil公认的答案中详细说明一些事情。 根据Git袖珍指南

科:

分支本身被定义为从命名提交(分支的“提示”)的提交图中可到达的所有点。

HEAD:一种特殊types的Ref

特殊的头部决定你在哪个分支…

参考文献

Git定义了两种引用或称为指针,它们称之为“refs”:

  • 一个简单的ref,它直接指向一个对象ID(通常是一个提交或标签)
  • 符号ref(或symref)指向另一个ref(简单的或符号的)

正如Greg所说,HEAD可以处于“分离状态”。 所以HEAD可以是简单的引用(对于分离的HEAD)或symref。

如果HEAD是一个现有分支的符号引用,那么你就在那个分支上。 另一方面,如果HEAD是通过SHA-1 ID直接命名提交的简单引用,则不是在任何分支上,而是在“分离的HEAD”模式下,承诺检查。

我认为“头”是目前检查提交。 换句话说,“HEAD”指向当前签出的提交。

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

一个很好的方法来回答正确的答案的重点是运行git reflog HEAD ,你会得到HEAD指出的所有地方的历史logging。

读完所有以前的答案后,我仍然想要更清晰。 在官方的git网站http://git-scm.com/blog上的这个博客给了我我正在寻找的东西:;

HEAD:指向上次提交快照的指针,下一个父级

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

头指向当前签出的分支的提示。

在这里输入图像描述

在你的仓库中,有一个.git文件夹。 在这个位置打开文件:.git \ refs \ heads。 该文件中的(sha-1散列)代码(大多数情况下是master)将是最近的提交,即在命令git log的输出中看到的代码。 有关.git文件夹的更多信息: http : //gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html

这两个可能会让你困惑:

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

当前分支,或者你的工作树通常是从HEAD指向的树中产生的。 HEAD必须指向头部,除非使用分离的头部。

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

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

作为一个概念,头是最新的一个分支。 如果每个命名分支有多个头,则可能是在不进行合并的情况下进行本地提交时创build的,从而有效地创build了一个未命名的分支。

要有一个“干净的”存储库,每个命名分支应该有一个头,并且在本地工作之后总是合并到一个命名分支。

Mercurial也是如此。