为什么git检查origin / master导致detached-HEAD

时间:2016-10-06 10:08:23

标签: git branch

正如标题所说,为什么会发生这种情况?

如文档和教程origin / master中所述 实际上是远程分支的本地副本。 那么为什么检查它会导致分离的HEAD,如果它是“只是分支的本地副本”

1 个答案:

答案 0 :(得分:3)

这就是在Git中定义分支的方式。

具体来说,分支 - 即普通的普通本地分支 - 是一种参考。标签也是如此,远程跟踪分支也是如此。彼此之间的区别在于它的完整名称,就像你在一个名叫Bob的几个人的派对上一样,他们可能至少有不同的全名。

分支名称以refs/heads/开头,而远程跟踪分支以refs/remotes/开头,后跟远程名称。这意味着refs/heads/master是分支名称,而refs/remotes/origin/master是远程跟踪分支名称。

引用通常指向提交

这些"参考"事物只是存储(一个,一个)Git对象的ID,通常是提交。

Git中的单词" branch"是不明确的

虽然我们将master称为分支,但它实际上是分支名称。因此,它是一个引用,它存储单个提交的ID。哪个提交?好吧,它是分支的提示。但那么<形容词>是一个分支?

Git分支也是一组提交。 Git 找到集合的方式是从分支名称开始,它为分支提供了 tip 提交的ID。通过该提交,Git可以找到一个或多个早期提交,称为该提交的。从这些提交中,Git可以找到他们的父母,依此类推,随着时间的推移。

当人们谈论"分支"在Git中,你必须从上下文中确定它们是否意味着"分支名称","分支上的提示提交",或者#34;该分支上的一些提交,可能同时排除该分支上的提交其他一些分支。"

有关此问题的更多内容,请参阅What exactly do we mean by "branch"?

当您git checkout分支名称时,您将被置于该分支

使用git checkout mastergit checkout develop,告诉Git您希望"进入"给定的分支。实际上这是如何工作的,Git将分支名称转换为完整的引用名称 - refs/heads/branch - 并将该名称写入文件.git/HEAD。也就是说,您的HEAD只是记录当前分支的名称

在此(附加头)模式下,HEAD文件充当间接引用。分支的尖端仍然记录在"真实"引用,以全名存储。由于好的或坏的原因(我们稍后会看到一些),Git 限制允许存储在HEAD中的字符串:它们只能是以refs/heads/

由于refs/remotes/origin/master不是以refs/heads/开头,因此您根本不被允许在""" refs/remotes/origin/master。同样,您不能使用refs/tags/v2.1之类的标记:也不能以refs/heads/开头。因此,如果您尝试查看其中一个,Git会让您进入"分离的HEAD"模式。

分离的HEAD

在"分离的HEAD"模式,Git记录.git/HEAD文件中提交的原始哈希ID,而不是记录当前分支的名称。这意味着你不会" on"任何分支。但是,Git仍然允许您进行新的提交,或者在历史记录中移动:当您执行上述任何操作时,它会根据需要将新ID存储到.git/HEAD

大多数情况下,分离的HEAD模式适合查看历史记录。它也可以在git rebase之类的命令下使用,它可以复制整个提交链,然后调整分支名称。

因此,如果HEAD中有一个哈希ID,那么它就会被分离,这是您当前的提交。否则,HEAD中有一个分支名称(以refs/heads/开头),并且该分支名称存储("指向")分支的提示提交的ID

为了找出您所在的分支,Git会读取HEAD。如果它有一个原始哈希ID,那么你就不会#34;"任何分支(虽然实际上你是在一个特殊的匿名分支上)。否则Git剥离refs/heads/部分并将其打印为分支的名称。

HEAD中禁止远程跟踪分支机构名称的原因1:没有refs/heads/剥离。

分支如何成长

分支机构通过提交新提交而成长。要进行新的提交,Git:

  1. HEAD读取当前提交ID(如果它是间接的,则跟随它到分支引用)。
  2. 将新提交的 parent 设置为在步骤1中获取的ID(以及作者和提交者,树和日志消息)。这个新提交获得一个新的,唯一的哈希ID。
  3. 将步骤2中获取的哈希ID写入HEAD(如果它是间接的,则将其跟随分支引用)。
  4. 这个新提交现在指向上一个分支提示,并且因为新ID现在存储在分支名称中,所以新提交现在是您的分支的尖端。继续!

    但是这会立即导致原因2禁止远程跟踪分支:进行新的提交会导致您无法正确跟踪远程。远程跟踪引用应该指向提交您从遥控器获得,而不是你在当地制造的。

    显然,这两个原因都可能有答案(例如,在远程跟踪分支或标签上禁止新提交,并在必要时拼出完整的引用)。但是Git设计师显然不喜欢这样,并且更喜欢"分离的HEAD"而是模式的东西。