为什么“remotes/origin/HEAD”有时会映射到“origin/master”,有时则不会?

Jam*_*ith 4 git github

在我的一些存储库中我看到......

> git branch --all
* master
  remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

...而在其他人中我看到:

> git branch --all
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

前者让我觉得正确,后者让我不安。这里发生了什么?

我之前已经添加了一个common映射到不同存储库的附加分支,并且设置它可能会导致问题。这个额外的分支现已被删除,但后一个存储库中的这个奇怪的设置仍然存在。任一存储库中都没有额外的遥控器,只有标准遥控origin器。

在我看来,第一个remotes/origin/master是 的缩写remotes/origin/master -> origin/master。只有当本地和远程分支在某些方面有所不同时,才需要明确说明映射吗?那么,有这种奇怪的remotes/origin/HEAD -> origin/master映射吗?如果用这个词来形容的话,那么这似乎是优先的?

tor*_*rek 7

马克·阿德尔斯伯格的回答涵盖了如何获得这些(git clone制造它们)。但让我们更普遍地看一下分支名称,然后是 Git 所说的引用符号引用

\n\n

您已经知道分支名称相对简单:它们只是类似于master和 的字符串develop。而且,由于git branch --all输出,您还知道您拥有 Git 有时所说的远程跟踪分支名称,例如origin/master. 我更喜欢称呼这些远程跟踪的名字,以避免过多使用“分支”这个词。

\n\n

您可能不知道的是,这两者只是 Git 将所有内容组合在一起的特殊形式。像这样的常规分支名称master实际上是一个全名拼写为 的引用refs/heads/master。远程跟踪名称就像origin/master是一个全名拼写为 的引用refs/remotes/origin/master。标签也只是全名以 开头的引用refs/tags/

\n\n

如果您运行git branch -r,它仅列出远程跟踪名称,您将看到origin/master而不是remotes/origin/master. refs/remotes/这是因为 Git 对于它剥离了多少部分并不总是一致的。(我不知道为什么Git 在这里不一致。)不过,一般来说,Git 喜欢将这些事情缩小到更易于管理的程度。由于所有引用始终以 \xe2\x80\x94 开头,refs/这就是Git定义它们的方式\xe2\x80\x94,一般来说,您可以始终删除该refs/部分,并且通常更多:您通常可以1删除refs/heads/refs/remotes/refs/tags/

\n\n

引用对你的作用\xe2\x80\x94嗯,每个引用的一个非常重要的部分\xe2\x80\x94是保存你在输出中看到的那些又大又难看的Git哈希ID之一git log。在内部,Git需要这些哈希 ID。不过,对于人类来说,它们是完全不可能使用的,因此 Git 为我们提供了可以用来记住 ID 的名称。

\n\n

但是有一个特殊情况允许任何引用,尽管最明智的做法是为使用单词的人保留它HEAD。任何引用都可以是符号引用。一个引用可以包含另一个引用的名称,而不是包含一个又大又难看的哈希 ID。然后 Git 会将名称转换为存储在另一个中的哈希ID引用中的哈希 ID。

\n\n

因此,如果refs/remotes/origin/HEAD包含名称 refs/remotes/origin/master,您可以说origin/HEAD任何您能说的地方origin/master。这并没有多大帮助\xe2\x80\x94I,至少,发现origin/HEAD用全大写的HEAD\xe2\x80\x94 来输入比较困难,但是 Git 添加了另一个特殊情况:如果你origin单独使用该名称,在当 Git “想要”一个哈希 ID 的地方,Git 会注意到origin对应于 的地方refs/remotes/origin/,然后查看它是否refs/remotes/origin/HEAD存在。Git 会读取它并发现这refs/remotes/origin/HEAD是对refs/remotes/origin/master. Git 会读取该内容并查看哈希 ID\xe2\x80\x94,现在 Git 将知道您所指的哈希 ID。

\n\n

因此,如果origin/HEAD(或refs/remotes/origin/HEAD)“指向” origin/master,则意味着您可以origin在通常需要写出的几个地方写入origin/master

\n\n

您可以使用命令(特别是其子命令)操作这些特殊的远程跟踪HEAD名称。我自己从来没有真正关心过这些\xe2\x80\x94我只是在我的意思是输入时输入,并忽略符号git remoteset-headorigin/masterHEAD与这些远程跟踪名称相关的符号。但如果您喜欢它们,它们就在那里供您使用。

\n\n
\n\n

1我在这里说“通常”是因为有一种特殊情况:如果你不小心将该名称foo同时用作分支名称 ( refs/heads/foo)标签名称 ( refs/tags/foo),那么仅仅说 就会突然成为一个问题foo。一种解决方案是拼出heads/fooand tags/foo, or Even refs/heads/foogitrevisions 文档中有更多关于此的详细信息

\n

  • 同样的`git remote`命令包含了所有的内容:`git remote set-head origin --delete`意思是“删除‘origin’的符号‘HEAD’”。正如我上面提到的,我曾经这样做过(当它需要手动干预时,“git remote set-head”还不存在),但没有真正的意义。 (2认同)