2023-04-02 05:00:03

Git中的HEAD是什么?

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

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

但Git HEAD到底是什么?


当前回答

我还在弄清楚git的内部结构,到目前为止,我已经弄清楚了这个:

假设当前的分支是master。

HEAD是你的.git/目录下的一个文件,通常看起来像这样:

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

Refs /heads/master本身是一个文件,通常包含master最新提交的哈希值:

% cat .git/refs/heads/master 
f342e66eb1158247a98d74152a1b91543ece31b4

如果你做git日志,你会看到这是master的最新提交:

% git log --oneline 
f342e66 (HEAD -> master,...) latest commit
fa99692 parent of latest commit

所以我的想法是HEAD文件是一种跟踪最新提交的方便方法,而不是记住长散列值。

其他回答

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

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

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

Git中的HEAD是什么?(概念)

HEAD是一个指向当前签出分支或提交的指针,它回答了一个问题:我现在在存储库的哪个位置?或者,换句话说,它是Git知道在哪个提交上镜像本地工作树的方式,以及您当前是否在一个分支上工作(附加的)或没有(分离的)。

分离的头

HEAD可以处于附加或分离两种状态之一,这取决于是否签出了分支。默认状态是附加的,其中对历史的任何操作都会自动记录到HEAD当前引用的分支。

在分离状态下,可以在不影响任何现有分支的情况下进行实验更改。请参见下面的信息图,说明在附加状态和分离状态下提交的区别。

一个常见的误解是,消息You are in 'detached HEAD' state是错误的语气,而实际上它只是描述HEAD是如何引用当前快照的。

可以使HEAD处于分离状态的操作:

签出一个特定的提交,即。 $ git checkout 14ko3 显式地签出一个远程分支,即。 $ git checkout origin/master 使用分离标志切换到一个分支,即。 $ git主开关——分离 签出一个标签,即 $ git checkout v1.0.1 执行交互式重基,或包含冲突更改的常规重基

从分离到依附的状态

要从分离状态切换到附加状态,您可以从所在的位置创建一个新分支,或者切换回现有的分支。

注意:如果你切换到另一个现有的分支,在分离状态下创建的任何提交最终(垃圾收集后)都会被丢弃,而不是首先在一个新的分支中持久化你的更改。

检查HEAD的状态

可以通过不同的方法来确定HEAD当前处于哪个状态,这里有两个选项。

使用显示 $ git show HEAD—一行 14ko3 (HEAD, master) C1 #如果附加,输出将是 14ko3 (HEAD -> master) C1 使用状态 $ git状态 HEAD在14ko3分离

HEAD到底是什么?(技术)

如果您想显式地查看HEAD引用了什么,您可以检查. Git /HEAD文件,这是Git内部用于管理HEAD的实际文件。该文件包含分支的名称或提交散列,这取决于是否分离HEAD。

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

# If detached, the output would have been
14ko36e295f1a98ec57397b3acc7bc247da61ff5

来源:以上节选自这篇关于主题的完整文章:Git中的HEAD是什么?

作为一个概念,头是分支中的最新修订。如果每个命名分支有多个头,那么在进行本地提交时可能会创建它,而没有合并,这实际上创建了一个未命名的分支。

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

Mercurial也是如此。

引用别人的话:

A head is simply a reference to a commit object. Each head has a name (branch name or tag name, etc). By default, there is a head in every repository called master. A repository can contain any number of heads. At any given time, one head is selected as the “current head.” This head is aliased to HEAD, always in capitals". Note this difference: a “head” (lowercase) refers to any one of the named heads in the repository; “HEAD” (uppercase) refers exclusively to the currently active head. This distinction is used frequently in Git documentation.

可以在这里找到另一个很好的源代码,它可以快速覆盖git的内部工作原理(因此可以更好地理解heads/HEAD)。引用(ref:)或头或分支可以被看作是粘贴在提交历史记录中的提交上的便利贴。通常它们指向一系列提交的提示,但它们可以随着git checkout或git reset等移动。

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

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

so

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

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