您会看到Git文档说出类似
分支必须在HEAD中完全合并。
但是Git HEAD
到底是什么?
您会看到Git文档说出类似
分支必须在HEAD中完全合并。
但是Git HEAD
到底是什么?
Answers:
您可以将HEAD视为“当前分支”。当您使用切换分支时git checkout
,HEAD版本将更改为指向新分支的尖端。
您可以通过执行以下操作查看HEAD指向的内容:
cat .git/HEAD
就我而言,输出为:
$ cat .git/HEAD
ref: refs/heads/master
HEAD可能引用与分支名称不相关的特定修订版。这种情况称为HEAD分离。
引用其他人:
头仅仅是对提交对象的引用。每个头都有一个名称(分支名称或标签名称等)。默认情况下,每个存储库中都有一个称为master的头。存储库可以包含任意数量的头。在任何给定时间,都会选择一个头作为“当前头”。该头别名为HEAD,始终以大写字母开头。”
注意这种区别:“头”(小写)是指存储库中任何已命名的头;“ HEAD”(大写)专门指当前活动的head。这种区别在Git文档中经常使用。
在这里可以找到另一个快速介绍git内部工作原理的好资料(因此可以更好地理解heads / HEAD)。引用(ref :)或标题或分支可以视为粘贴在提交历史中的提交上的便利贴。通常,它们指向一系列提交的尖端,但是可以使用git checkout
or git reset
等来移动它们。
git checkout HEAD~2
),而不是已知磁头的提交ID。有关更详尽的解释,请参阅eagain.net/articles/git-for-computer-scientists上的文章。
git revert
,并不是将分支移到最末端的一个好例子,因为git revert
只是创建了一些新的提交,而仍然将当前分支留在了(新)末端。
commit
S,reset
S等
我从github开发人员Scott Chacon [ 视频参考 ] 推荐此定义:
头是您当前的分支。它是一个符号参考。它是对分支的引用。您始终具有HEAD,但是HEAD将指向这些其他指针之一,您所在的分支之一。它是您下次提交的父项。这应该是最后签出到您的工作目录中的内容。这是您的工作目录的最新已知状态。
整个视频将公平地介绍整个git系统,因此,如果有时间,我也建议您观看所有视频。
HEAD只是一个特殊的指针,它指向您当前所在的本地分支。
从Pro Git书籍的第3.1章Git分支-坚果壳中的分支,创建新分支一节中:
如果创建一个新分支会怎样?好吧,这样做会创建一个新的指针供您移动。假设您创建了一个名为testing的新分支。您可以使用git branch命令执行此操作:
$ git branch testing
这将在您当前正在执行的同一提交处创建一个新的指针
Git如何知道您当前在哪个分支?它保留一个称为HEAD的特殊指针。请注意,这与您可能习惯的其他VCS中的HEAD概念有很大不同,例如Subversion或CVS。在Git中,这是指向您当前所在的本地分支的指针。在这种情况下,您仍处于掌握状态。git branch命令仅创建一个新分支,但未切换到该分支。
34ac2
在上面的示例中签出,那么HEAD将指向该提交,这称为分离的HEAD。在这种状态下,您也可以进行更改,试验和提交更改,但是一旦签出其他分支,您将丢失所有更改,除非您当然创建了一个新分支。
git log
并得到了类似的信息commit ad0265... HEAD -> foo ...
,则意味着该foo
分支是对commit id的引用ad0265
。签出文本参考foo
不是一个独立的头。对提交ID进行检出ad0265
将导致头部分离。可能是我错过了您所传达的内容的一些微妙之处。我希望这堵文字墙有助于发现我迷路的地方。
这些答案在许多方面都有一个,也许是微妙但重要的误解。我以为我会添加我的答案来清除它。
什么
HEAD
啊
HEAD
是一个符号引用,指向您在提交历史记录中的任何位置。无论您走到哪里,无论做什么,它都会跟随您,就像阴影一样。如果您提交,HEAD
将移动。如果您结帐,HEAD
将会移动。无论您做什么,如果您在提交历史记录HEAD
中移到了新的位置,都会与您一起移动。要解决一个常见的误解:您不能脱离HEAD
。那不是分离的HEAD状态。如果您发现自己在想:“哦,不,我处于HEAD分离状态!我迷失了HEAD!” 记住,这是你的头。HEAD是你。您尚未与HEAD分离,您和您的HEAD已与其他物体分离。
HEAD
可以指向一个提交,是的,但是通常不是。让我再说一遍。通常HEAD
不指向提交。它指向分支引用。它附属于该分支,并且当您执行某些操作(例如commit
或reset
)时,附属的分支将与一起移动HEAD
。您可以通过在引擎盖下查看来查看其指向的内容。
cat .git/HEAD
通常,您会得到以下内容:
ref: refs/heads/master
有时您会得到如下信息:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
这就是当HEAD
直接指向提交时发生的情况。这称为分离的HEAD,因为HEAD
它指向的是分支引用以外的内容。如果您在这种状态下进行提交master
,不再被附加到HEAD
,将不再与您一起移动。提交在哪里都没有关系。您可能与主分支位于同一提交上,但是如果HEAD
指向的是提交而不是分支,则它是分离的,并且新的提交不会与分支引用关联。
如果尝试以下练习,则可以以图形方式查看。从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仍指与分支名称关联的特定修订版。我们仍然在 master分支上,不是吗?
现在尝试:
git status
# HEAD detached at a3c485d
不。我们处于“分离头”状态。
你可以看到相同的表示(HEAD -> branch)
对(HEAD, branch)
用git log -1
。
HEAD
是你。无论您身在何处,它都指向您签出的所有内容。通常,这不是提交,而是分支。如果HEAD
确实指向一个提交(或标签),即使它与分支也指向同一提交(或标签),则您(和HEAD
)已与该分支分离。由于您没有附加分支,因此在您进行新提交时,该分支也不会跟随您。HEAD
但是会。
.git/HEAD
该软件认为是HEAD。
HEAD
指的是您的工作副本指向的当前提交,即您当前已签出的提交。从官方的Linux内核文档中获取有关指定Git修订版的信息:
HEAD
在工作树中命名所做更改的提交。
但是请注意,在即将发布的Git 1.8.4版本中,@
也可以用作Git 的简写HEAD
,正如Git贡献者Junio C Hamano在其Git Blame博客中指出的那样:
不用输入“ HEAD”,也可以说“ @”,例如“ git log @”。
Stack Overflow用户VonC 在回答另一个问题时还发现了一些有趣的信息,@
这些信息说明了为什么选择为什么速记。
同样令人感兴趣的是,在某些环境中,不必大写HEAD
,特别是在使用不区分大小写的文件系统的操作系统中,尤其是Windows和OSX。
看看创建和使用分支
HEAD实际上是一个文件,其内容确定HEAD变量引用的位置:
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
在此存储库中,HEAD文件的内容引用了另一个名为refs / heads / master的文件。文件refs / heads / master包含master分支上最近提交的哈希。
结果是HEAD指向.git / refs / heads / master文件中的master分支提交。
我想详细介绍Greg Hewgil接受的答案中的一些内容。根据Git Pocket Guide
科:
分支本身定义为提交图中从命名提交(分支的“尖端”)到达的所有点。
HEAD:特殊类型的Ref
特殊的ref HEAD决定了您所在的分支...
参考
Git定义了两种引用或命名的指针,它们称为“引用”:
- 一个简单的ref,直接指向对象ID(通常是提交或标记)
- 一个符号引用(或symref),它指向另一个引用(简单或符号)
如Greg所述,HEAD可以处于“分离状态”。因此,HEAD可以是简单的ref(对于分离的HEAD),也可以是symref。
如果HEAD是现有分支的符号引用,则您位于该分支上。另一方面,如果HEAD是直接通过其SHA-1 ID命名提交的简单引用,则您不是“在”任何分支上,而是在“分离的HEAD”模式下,这种情况在您较早签出时会发生。致力于检查。
我认为“ HEAD”是当前的检出提交。换句话说,“ HEAD”指向当前已签出的提交。
如果您只是克隆但没有签出,我可能不知道它指向什么,可能是某个无效的位置。
master
分支-HEAD将指向master。
master
,但并非总是如此。见remote set-head
remote set-head
,该引用仅影响本地默认分支,不会更改服务器上的默认值。
Head指向当前已签出分支的尖端。
在您的存储库中,有一个.git文件夹。在以下位置打开文件:.git \ refs \ heads。该文件(在大多数情况下为master)中的(sha-1哈希)代码将是最近的提交,即在命令输出中看到的提交git log
。有关.git文件夹的更多信息:http : //gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html
git reset HEAD^
,然后分支的尖端不再指向最近的提交(前一个尖端)。
阅读完所有先前的答案后,我仍然希望更加清晰。这个官方git网站http://git-scm.com/blog上的博客为我提供了我想要的东西:
Git中的HEAD是指向当前分支引用的指针,而该分支引用又是指向您进行的最后一次提交或签出到工作目录中的最后一次提交的指针。这也意味着它将成为您下次提交的父项。通常认为它是最简单的,因为HEAD是您最后一次提交的快照。
HEAD
不是提交;它指向一个。
checkout HEAD^
,那么HEAD甚至都不会指向任何分支上的最后一个提交快照。
commit
,merge
,rebase
,log
,等,但在概念上,也许“(指针)的当前位置”是一个很好的总结。
感觉这HEAD
只是您签出的最后一次提交的标签。
这可以是特定分支的提示(例如“ master”),也可以是某个分支的中间提交(“ headed”)
看看http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is
图3-5。HEAD文件指向您所在的分支。
从概念上讲,头部是分支中的最新版本。如果每个命名分支有多个头,则可能在执行本地提交而不合并时创建了它,从而有效地创建了一个未命名分支。
要拥有一个“干净的”存储库,每个命名分支应该有一个头,并且在本地工作后始终合并到一个命名分支。
对于Mercurial来说也是如此。