在我的一些资料库中,我看到......
> git branch --all
* master
remotes/origin/master
......而在其他人看来:
> git branch --all
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
前者让我觉得正确,后者让我感到不安。这里发生了什么?
我之前已经包含了一个映射到不同存储库的额外common
分支,并且设置它可能导致了这个问题。这个额外的分支现在已被删除,但后一个存储库中的这个奇怪的设置仍然存在。两个存储库中都没有其他远程控制器,只有标准origin
存储库。
在我看来,在{1}中,remotes/origin/master
是remotes/origin/master -> origin/master
的缩写。只有当本地和远程分支在某些方面有所不同时,才需要明确说明映射?所以有这个奇怪的remotes/origin/HEAD -> origin/master
映射,如果这是它的单词,它似乎优先考虑?
答案 0 :(得分:2)
第remotes/origin/HEAD -> origin/master
行只是告诉您哪个分支origin
已签出 - 这又是在新克隆中签出的默认分支。
(我可能应该说,当最后一次本地origin
引用更新时,哪个分支remotes/origin/HEAD
已经检出。在我的测试中,这个引用只在更新时才更新克隆最初是创建的。可能有一些方法我没想到要强制它更新。)
如果你有一个回复,你不看到这一行,这可能意味着在制作克隆时没有检出分支 - 例如如果你克隆了一个空的存储库。
答案 1 :(得分:2)
Mark Adelsberger's answer涵盖了 这些(git clone
制作它们)的方式。但是让我们更一般地看一下分支名称,然后是Git所谓的引用和符号引用。
您已经知道分支名称相对简单:它们只是master
和develop
之类的字符串。而且,由于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/
部分,通常更多:您通常可以 1 放弃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又增加了另一个特例:如果使用名称{{1}在Git“想要”哈希ID的地方,Git会注意到origin
对应origin
,然后看到refs/remotes/origin/
存在。 Git会阅读它并看到refs/remotes/origin/HEAD
是refs/remotes/origin/HEAD
的符号引用。 Git将读取 并查看哈希ID - 现在Git将知道您的哈希ID。
因此,如果refs/remotes/origin/master
(或origin/HEAD
)“指向”refs/remotes/origin/HEAD
,则表示您可以在通常需要写的几个地方写origin/master
out origin
。
您可以使用the git remote
command操作这些特殊的远程跟踪origin/master
名称,特别是使用其HEAD
子命令。我自己从来没有真正打扰任何这些 - 我只是在我的意思是输入set-head
,并忽略与这些远程跟踪名称一起使用的符号origin/master
。但如果你喜欢它们,它们就可供你使用。
1 我在这里说“通常”,因为有一个特例:如果你不小心将名称HEAD
作为分支名称(foo
) 和标记名称(refs/heads/foo
),只是说refs/tags/foo
突然变成了问题。一种解决方案是拼出foo
和heads/foo
,甚至是tags/foo
。有关此内容的详细信息,以及the gitrevisions documentation中的更多内容。