在 git pull
之后,我总是能够通过执行 git branch
来查看所有分支。
现在(出于某种原因)运行 git branch
向我展示了 master 和另一个我正在积极工作的分支。git remote show origin
向我展示了所有分支。如果我对其中一个执行 git checkout
,它会在本地 pull 下分支并交换到它。之后,当我运行 git branch
时它是可见的
问题
当我运行 git branch
时,如何让远程分支再次显示?
注意:这只是一个视觉问题 - 我仍然可以毫无问题地访问我的远程分支,我只是想知道为什么当我执行 git 分支时它们没有像通常那样显示
最佳答案
TL;DR:只需使用 git branch -r
或 git branch -a
(在 git fetch
之后更新)。完全不清楚为什么您会看到没有这些标志的远程跟踪分支(也许您一直在使用自动显示它们的 GUI?)。
但是,您的问题中至少存在一个小的误解——这并不奇怪; Git 的这个特殊部分起初很棘手。
事实上,这个问题涉及三组分支名称。
git remote show origin
shows me all branches.
不完全是。让我们稍微备份一下,并定义两个分支集合(或类,或任何您喜欢将它们分组的词)。 Git 提供:
git branch
在不带参数和标志的情况下显示的内容。$ git branch
diff-merge-base
* master
precious
stash-exp
“分支”一词通常表示其中之一:一个名称,当输入
git rev-parse
时,解析为提交 ID:$ git rev-parse diff-merge-base
2d0cc5001c1a88995727521d4ef77f7a4acc4e14
并且其全名以
refs/heads/
开头:$ git rev-parse --symbolic-full-name diff-merge-base
refs/heads/diff-merge-base
git branch -r
显示的内容:$ git branch -r
origin/HEAD -> origin/master
origin/maint
origin/master
origin/next
origin/pu
origin/todo
它们之间的主要区别在于,您的本地分支是您可以随意操作的名称,而您的远程跟踪分支是您的名称,Git 会自动从属于其他东西。您可以自己操作它们,但这没有利润,因为它们的目的是记住一些其他 Git 的分支名称(以及相应的 SHA-1 值)。
请注意,将远程跟踪分支名称提供给
git rev-parse
也是有效的,您也可以获得它的 symbolic-full-name
:这只是以 refs/remotes/
开头,后跟远程名称,然后是本地名称,如果您看到的是 Git在 Remote 上运行 。因此:$ git rev-parse --symbolic-full-name origin/master
refs/remotes/origin/master
意味着我的 Git 的
origin/master
是我的 Git 对 master
的含义的内存,在 origin
上,我的 Git 上次调用 0x2518122313,4314 和 .1 和..origin
(有时)实际上调用了远程Git请记住,每次获取或推送提交时,都会涉及两个(有时甚至更多)Git 版本控制数据库。所以你可以查看你的信息,或者你可以让你的 Git 通过互联网电话调用他们的 Git,并查询他们的信息。他们也可能拥有自己的本地分支机构,甚至远程跟踪分支机构。 (通常,对于这种情况,他们只有本地分支机构。)
出于说明目的,让我删除我自己的一个远程跟踪分支(这是非常无害的,因为我稍后将运行
git remote
来恢复它):$ git branch -r -d origin/pu
Deleted remote-tracking branch origin/pu (was 7c79844).
现在,如果我运行
git fetch
我将不再有 git branch -r
:我的 Git 不再将其作为远程跟踪分支。但是他们的 Git 在 origin/pu
上仍然有一个名为 origin
的本地分支,所以:$ git remote show origin
* remote origin
Fetch URL: git://git.kernel.org/pub/scm/git/git.git
Push URL: git://git.kernel.org/pub/scm/git/git.git
HEAD branch: master
Remote branches:
maint tracked
master tracked
next tracked
pu new (next fetch will store in remotes/origin)
todo tracked
Local branches configured for 'git pull':
master merges with remote master
stash-exp merges with remote master
Local ref configured for 'git push':
master pushes to master (local out of date)
当我运行
pu
时,我的 Git 调用他们的 Git(这恰好是 Git 的 Git 存储库的副本——现在 github.com 上还有另一个可能更合适)并从他们那里获取所有分支的列表.我已经将其中大部分作为我自己的“远程跟踪分支”,但我删除了 git remote show origin
,因此它显示为"new"。一个类似的命令
pu
也调用另一个 Git 并查询它,但会显示更多信息:它会显示每个分支的提交哈希(以及每个标签的对象哈希)。有很多标签,所以让我将其限制为一个分支:$ git ls-remote origin master
e05806da9ec4aff8adfed142ab2a2b3b02e33c8c refs/heads/master
在这两种情况下,你的 Git(或我的 Git)调用他们的 Git 并从他们那里获取信息,但它只是显示它,而不是保存它。为了保存信息,我们必须运行
git ls-remote
。我有一段时间没有运行它,所以:$ git fetch origin
remote: Counting objects: 2064, done.
remote: Compressing objects: 100% (1294/1294), done.
remote: Total 2064 (delta 1383), reused 1118 (delta 767)
Receiving objects: 100% (2064/2064), 2.12 MiB | 2.29 MiB/s, done.
Resolving deltas: 100% (1383/1383), done.
From git://git.kernel.org/pub/scm/git/git
de2efeb..e05806d master -> origin/master
3074f94..c69c2f5 next -> origin/next
* [new branch] pu -> origin/pu
1a46792..2135c1c todo -> origin/todo
这个
git fetch
和 git fetch
和 git remote show
做了同样的事情,但也做了更多的事情:它收集了我需要完成我的存储库的对象,然后更新我的远程跟踪分支名称以对应于它们的存储库中的分支名称。这就是为什么我重新获得了
git ls-remote
:他们仍然有一个 origin/pu
,而我丢弃了我的,所以我获得了他们的,现在又拥有了。这也是我更新除
pu
之外的所有其他内容的原因:时间已经足够长,它们都已更新。我的 maint
过去指的是提交 origin/master
,但现在它指的是 de2efeb
,这与我们在上面运行 0x25181223134314 时看到的 ID 相同(这意味着他们没有在我输入所有内容的几分钟内更新他们的 e05806d
。想象一下,数十亿纳秒没有更新!:-))(请注意,
git ls-remote
跳过了 master
的调用,只是向您展示了您的 Git 记录的内容。其他几个 git remote show -n origin
命令也可以在本地运行;请参阅文档了解具体信息。)概括
回顾一下,这里涉及三组分支名称:
大多数情况下,最后一组分支名称无关紧要。大多数时候,您在自己的存储库中工作。只涉及一个 Git,它是你的。他们的 Git 有自己的分支,就在图片之外。
但有时——啊,这样的时候!——有时,你必须将你的 Git 连接到另一个 Git。现在他们的名字很重要!这里真正棘手的事情是你的名字根本不需要匹配他们的名字。您的
origin
必须与它们的 git remote
相对应并没有硬性的理由——但是您的 Git 会将它们的 master
复制到您的 master
中,如果它们的名称与您的大脑名称匹配,那么它会保存很多名称。您可以解决这个问题(以多种不同的方式),但在您遇到真正需要它的情况之前不要这样做(多个 Remote 使用冲突的分支名称——这几乎从未发生过)。master
怎么样?您在上面指出:
If I do a
git checkout
on one of [their branch names that I don't see ingit branch
output], it pulls the branch down locally and swaps to it.
假设您运行了
origin/master
(而不是 git checkout blah
)并看到了一个名为 git branch -r
的分支。假设您还没有名为 git remote show origin
的(本地)分支。你跑:$ git checkout zorg
你的 Git 说:
Branch zorg set up to track remote branch zorg from origin.
Switched to a new branch 'zorg'
你的 Git 没有在这里“pull 下”任何东西。它所做的是创建一个新的本地分支名称
origin/zorg
,指向与 zorg
相同的提交——同样丑陋的 SHA-1 哈希 ID。该提交已经在您的存储库中,随时可以 check out ,实际上您可以这样做:$ git checkout origin/zorg
看看它——但这会给你一个 Git 所谓的“分离的 HEAD”。
这里发生的事情是,在 Git 中,分支名称只是一个指向特定提交的可移动指针。
zorg
命令以这种方式使用时,会做两件事:检查一个特定的提交(进入工作树),以及切换 Git 对“当前分支名称”的概念。当您 origin/zorg
一个现有的、本地的、普通的分支名称时,Git 会检查有问题的一个提交,并将您置于“分支”上,如 git checkout
会说:$ git status
On branch master
当你
git checkout
任何提交不是一个简单的分支名称时,Git 仍然会检查一次提交,但会让你离开任何分支,即给你一个“分离的 HEAD”。我们从上面知道
git status
是(现在)提交 git checkout
,所以:$ git checkout origin/master
要么:
$ git checkout e05806da9ec4aff8adfed142ab2a2b3b02e33c8c
两者都做同样的事情。由于
origin/master
不是本地分支,我最终得到:$ git status
HEAD detached at e05806d
(或有时
e05806da9ec4aff8adfed142ab2a2b3b02e33c8c
)。因此,
origin/master
所做的是尝试将您给它的名称转换为分支名称。如果失败, HEAD detached at origin/master
有这个额外的内置功能:它搜索所有远程跟踪分支,看看是否有一个“主要匹配”名称的分支。因此 git checkout
检查名为 git checkout
的本地分支,但未能找到它,然后在所有远程跟踪分支中搜索与 git checkout zorg
匹配的分支。实际上只有一个——zorg
——所以这会触发特殊情况代码。特殊情况代码简单地实现了“创建新的本地分支设置以跟踪相应的远程跟踪分支”。也就是说,创建一个本地
zorg
,其上游(Git 现在称之为这些东西)设置为 origin/zorg
。请注意,要使其正常工作,必须恰好有一个合适的远程跟踪分支。如果我根本没有
zorg
,这将失败——如果我同时拥有 origin/zorg
和 origin/zorg
,其中 origin/zorg
是否也会失败,因为我的存储库是否会像另一个 2231 这样的 Git 指向第三个远程 0x2131,本地 thirdrepo/zorg
应该有 thirdrepo
或 origin
作为其上游。大多数情况下,您只有一个 Remote ,名为
zorg
。因此,只要您将 origin/zorg
的所有分支都保存为您自己的 Git 的远程跟踪分支内存,您就可以只使用 thirdrepo/zorg
这些名称来让您的 Git 创建它们。但有时你会发现你必须先运行 origin
才能更新你的远程跟踪分支。
关于git - 远程 Git 分支不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41406903/