为什么'遥控/原点/ HEAD'有时会映射到'origin / master',有时候不会?

问题描述 投票:1回答:2

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

> git branch --all
* master
  remotes/origin/master

...而在其他人看来:

> git branch --all
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

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

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

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

git github
2个回答
2
投票

remotes/origin/HEAD -> origin/master只是告诉你哪个分支origin已经检出 - 这又是在新克隆中检出的默认分支。

(我可能应该说,当最后一个本地origin ref更新时,哪个分支remotes/origin/HEAD已经检查过。在我的测试中,这个ref只在最初创建克隆时才更新。可能有些方法我没有想到强制它要更新。)

如果你有一个你没有看到这一行的回购,这可能意味着在制作克隆时没有检出分支 - 例如如果你克隆了一个空的存储库。


2
投票

Mark Adelsberger's answer介绍了如何获得这些(git clone制作它们)。但是让我们更一般地看一下分支名称,然后Git调用引用和符号引用。

你已经知道分支名称相对简单:它们只是像masterdevelop这样的字符串。而且,由于git branch --all输出,你也知道你有Git有时称为远程跟踪分支名称,如origin/master。我更喜欢称这些远程跟踪名称,以避免使用“分支”这个词太多。

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

如果运行仅列出远程跟踪名称的git branch -r,您将看到origin/master而不是remotes/origin/master。这是因为Git并不总是关于它剥离了多少refs/remotes/部分。 (为什么Git在这里不一致,我不知道。)一般来说,Git喜欢将这些东西缩小到更容易管理的东西。因为所有引用总是以refs/开头 - 那就是how Git defines them - 一般来说,你可以放弃refs/部分,通常更多:你​​通常可以放弃refs/heads/refs/remotes/refs/tags/

什么参考对你有用 - 嗯,每个引用的一个非常重要的部分 - 是保存你见过的那些丑陋的Git哈希ID之一,例如git log输出。在内部,Git需要那些哈希ID。但是,对于仅仅是人类来说,它们是不可能的,所以Git给了我们可以用来记住ID的名字。

但是有一个特殊的情况允许任何参考,虽然最明智的做法是保留它用于使用HEAD这个词。任何引用都可以是符号引用。引用可以包含另一个引用的名称,而不是包含大的丑陋哈希ID。然后Git将名称转换为存储在另一个引用中的哈希ID。

因此,如果refs/remotes/origin/HEAD包含名称refs/remotes/origin/master,你可以说origin/HEAD,你可以说origin/master。这没什么帮助 - 至少,我发现用全大写origin/HEAD键入HEAD更难 - 但Git增加了另一个特殊情况:如果你自己使用名称origin,在Git“想要”的地方一个哈希ID,Git会注意到origin对应refs/remotes/origin/,然后看到refs/remotes/origin/HEAD存在。 Git会读它,看看refs/remotes/origin/HEADrefs/remotes/origin/master的象征性参考。 Git会读取它并查看哈希ID - 现在Git将知道您的哈希ID。

因此,如果origin/HEAD(或refs/remotes/origin/HEAD)“指向”origin/master,这意味着你可以在一些你通常必须写出origin的地方写origin/master

您可以使用HEAD操作这些特殊的远程跟踪the git remote command名称,特别是使用其set-head子命令。我自己从来没有真正打扰任何这个 - 我只是在我的意思是输入origin/master,并忽略与这些远程跟踪名称一起使用的符号HEADs。但如果你喜欢它们,它们就可以供你使用。


1我在这里说“通常”,因为有一个特殊情况:如果你不小心将foo这个名称作为分支名称(refs/heads/foo)和标签名称(refs/tags/foo),它就会突然变成一个问题,就是说foo。一个解决方案是拼出heads/footags/foo,甚至refs/heads/foo。在the gitrevisions documentation中有更多细节,还有更多。

© www.soinside.com 2019 - 2024. All rights reserved.