Mark Adelsberger的答案讲述了如何获取它们(git clone
会生成它们)。但是我们更加通俗易懂地来看待分支名称,以及Git所谓的引用和符号引用。
你已经知道分支名称相对简单:它们只是像master
和develop
这样的字符串。而且,由于git branch --all
输出,你也知道你拥有Git有时称为远程跟踪分支名称,例如origin/master
。我更喜欢将其称为远程跟踪名称,以避免过多使用"branch"这个词。
你可能不知道的是,这两者都只是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在一般情况下喜欢缩小这些东西以使其更易管理。由于所有引用始终都以
refs/
开头--这是
Git如何定义它们--通常你可以省略
refs/
部分,通常还可以省略
refs/heads/
、
refs/remotes/
和
refs/tags/
。
一个引用为你做的事情——其中非常重要的一部分——是保存那些你在例如
git log
输出中看到的巨大丑陋的Git哈希ID之一。Git内部需要这些哈希ID,但它们对于普通人来说相当难以使用,因此Git给我们提供了可以用来记住这些ID的名称。
但是有一种特殊情况允许
任何引用,尽管最好将其保留给使用单词
HEAD
的引用。任何引用都可以是
符号性引用。引用不包含一个巨大丑陋的哈希ID,而是包含另一个引用的名称。然后,Git会将该名称转换为存储在
其他引用中的哈希ID。
因此,如果
refs/remotes/origin/HEAD
包含
名称refs/remotes/origin/master
,则您可以在任何可以使用
origin/master
的地方使用
origin/HEAD
。这并没有太大帮助 - 至少我发现使用全部大写的
HEAD
更难输入 - 但是Git添加了另一个特殊情况:如果您仅使用
origin
名称,在Git“需要”哈希ID的位置,Git将注意到
origin
对应于
refs/remotes/origin/
,然后看到
refs/remotes/origin/HEAD
存在。Git将读取它并查看
refs/remotes/origin/HEAD
是指向
refs/remotes/origin/master
的符号引用。Git将读取
那个并查看哈希ID - 现在Git将知道您想要的哈希ID。
因此,如果
origin/HEAD
(或
refs/remotes/origin/HEAD
)“指向”
origin/master
,那么你可以在一些地方写
origin
,而不是写出
origin/master
。你可以使用
git remote命令来操纵这些特殊的远程跟踪
HEAD
名称,具体来说就是使用它的
set-head
子命令。我自己从未真正关注过这些内容——当我想要的是
origin/master
时,我只需键入该内容,并忽略与这些远程跟踪名称相关的符号
HEAD
。但如果你喜欢它们,它们就在那里供你使用。
1我在这里说“通常”是因为有一个特殊情况:如果您不小心将名称foo
作为分支名称(refs/heads/foo
)和标签名称(refs/tags/foo
),那么仅仅说foo
就会成为一个问题。一种解决方法是拼写出heads/foo
和tags/foo
,甚至是refs/heads/foo
。关于这个问题以及更多细节,请参考git修订文档。
origin\HEAD -> origin\master
这个是一种符号链接吗?对我来说,这似乎毫无意义。 - undefinedgit remote
命令中包含了所有的繁琐操作:git remote set-head origin --delete
的意思是 "删除origin
的符号化HEAD
"。如我之前提到的,我曾经这样做过(在需要手动干预的时候,git remote set-head
还不存在),但实际上并没有什么意义。 - undefined