远程Git分支不可见

Dan*_*iel 24 git

git pull我总是通过做一个看到所有分支后git branch.

现在(由于某种原因)跑步git branch显示我主人和另一个分支,我正在积极工作,.

git remote show origin告诉我所有的分支.如果我git checkout在其中一个上执行操作,它会在本地拉出分支并交换到它.之后,当我跑步时它是可见的git branch

我跑步时如何让远程分支再次显示git branch

注意:这只是一个视觉问题 - 我仍然可以毫无问题地访问我的远程分支,我只是想知道为什么当我做git分支时他们没有像往常一样出现

tor*_*rek 24

TL; DR:只需使用git branch -rgit branch -a(git fetch更新后).你不清楚为什么你看到没有这些标志的远程跟踪分支(也许你一直在使用自动显示它们的GUI?).

但是,你的问题中至少有一个小错误概念 - 这并不奇怪; Git的这个特殊部分起初很棘手.


事实上,这个问题涉及组分支名称.

git remote show origin 告诉我所有的分支.

不完全是.让我们稍微回顾一下,然后定义两个分支(或类,或者你喜欢的任何单词).Git提供:

这些之间的关键区别在于你的本地分支是你喜欢操纵的名字,而你的远程跟踪分支是你的名字,Git自动从属于其他东西.这是可能的,你自己对它们操作,但它不是赚钱的,因为他们的意图是要记住一些其他 Git的分支名称(以及相应的SHA-1的值).

请注意,提供一个远程跟踪分支名称git rev-parse 也可以工作,你也可以得到它symbolic-full-name:这只是开头refs/remotes/,然后是遥控器的名称,后跟本地名称,如果你是在运行的Git 看到的遥远的.因此:

$ git rev-parse --symbolic-full-name origin/master
refs/remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

意味着我的Git origin/master是我的Git 记忆master意思,在origin最后一次我的Git调用origin和获取 - 即更新 - 来自他们.

git remote (有时)实际上调用了远程Git

请记住,每次提取或推送提交时都会涉及两个(有时甚至更多)Git版本控制数据库.所以,你可以看到你的信息,或者您可以询问您的Git来调用它们的Git,通过互联网,电话和查询他们关于他们的信息.他们也可能拥有自己的本地分支机构,甚至是远程跟踪分支机构.(通常,对于这种情况,他们只有本地分支.)

为了便于说明,让我删除一个我自己的远程跟踪分支(这是非常无害的,因为我会git fetch在一段时间内运行以恢复它):

$ git branch -r -d origin/pu
Deleted remote-tracking branch origin/pu (was 7c79844).
Run Code Online (Sandbox Code Playgroud)

现在,如果我跑了,git branch -r我将不再拥有origin/pu:我的Git不再具有远程跟踪分支.但他们的 Git origin仍然有一个名为的本地分支pu,所以:

$ 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)
Run Code Online (Sandbox Code Playgroud)

当我运行时git remote show origin,我的Git调用他们的Git(这恰好是Git的Git存储库的副本 - github.com上的另一个可能更适合这些天)并从他们那里获得所有分支的列表.我已将其中大部分作为我自己的"远程跟踪分支",但我删除了pu,因此它显示为"新".

一个类似的命令,git ls-remote也会调用另一个Git并对其进行查询,但会向您展示更多信息:它会向您显示每个分支的提交哈希值(以及每个标记的对象哈希值).有很多标签,所以让我把它限制在一个分支:

$ git ls-remote origin master
e05806da9ec4aff8adfed142ab2a2b3b02e33c8c        refs/heads/master
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,你的Git(或我的Git)调用他们的Git并从中获取信息,但它只显示它,而不是保存它.要保存信息,我们必须运行git fetch.我有一段时间没有这样做,所以:

$ 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
Run Code Online (Sandbox Code Playgroud)

这和它git fetch做了同样的事情,但后来也做了更多的事情:它收集了我需要完成我的存储库的对象,然后更新我的远程跟踪分支名称以对应于其存储库中的分支名称.git remote showgit ls-remote

这就是为什么我重新获得origin/pu:他们仍然有一个pu,我放弃了我的,所以我获得了他们,现在再次拥有一个.

这也是为什么我更新了所有其他的,除了maint:它已经足够长,它们都已经更新了.我origin/master过去常常提到提交de2efeb,但现在它指的是e05806d,这与我们上面运行时看到的ID相同git ls-remote.(这意味着他们没有更新他们master在几分钟内我输入所有这些.想象一下,数十亿纳秒已经过去而没有更新!:-))

(注意,git remote show -n origin 跳过打开的电子邮件origin,并简单地向您显示Git记录的内容.其他几个git remote命令也在本地工作;请参阅文档以获取详细信息.)

摘要

回顾一下,这里涉及组分支名称:

  • 你当地的分公司;
  • 您的远程跟踪分支机构; 和
  • 他们的分支(在远程Git中).

大多数时候,最后一组分支名称无关紧要.大多数情况下,您在自己的存储库中工作.只涉及一个Git,它是你的. 他们的 Git拥有自己的分支,正如图所示.

但有时啊 - 这样的时候! - 有时,你必须把你的Git连接到另一个 Git. 现在他们的名字很重要 这里的真正棘手的事情是,你的名字不具有自己的名称相匹配的所有.有没有硬性的原因, master 必须符合他们的master-但你的 Git会复制他们 master你的 origin/master,所以它节省了大量的脑细胞,如果你的名字和自己的名字匹配.你可以解决这个问题(以多种不同的方式),但是在你遇到真正需要它的情况之前不要这样做(使用多个遥控器使用冲突的分支名称 - 这几乎不会发生).

怎么样git checkout blah

你在上面提到:

如果我git checkout在[他们的分支名称中我没有在git branch输出中看到]中的一个,它会在本地拉出分支并交换到它.

假设您已经运行git branch -r(而不是git remote show origin)并且看到了一个名为的分支origin/zorg.我们还说你还没有一个名为的(本地)分支zorg.你跑:

$ git checkout zorg
Run Code Online (Sandbox Code Playgroud)

而你的Git说:

Branch zorg set up to track remote branch zorg from origin.
Switched to a new branch 'zorg'
Run Code Online (Sandbox Code Playgroud)

你的Git没有"拉下" 任何东西.它所做的是创建一个新的本地分支名称,zorg指向同一个提交 - 同样大的丑陋SHA-1哈希ID origin/zorg.该提交已经在您的存储库中,随时可以检出,事实上您可以完成:

$ git checkout origin/zorg
Run Code Online (Sandbox Code Playgroud)

看看它 - 但这会给你Git称之为"独立的HEAD".

这里发生的是,在Git中,分支名称只是指向一个特定提交的可移动指针.git checkout当以这种方式使用时,该命令做件事:检查一个特定的提交(进入工作树),切换你的Git的"当前分支名称"的概念.当你git checkout是一个现有的,本地的普通分支名称时,Git检查出一个有问题的提交,并将你"放在分支"上,如下所示git status:

$ git status
On branch master
Run Code Online (Sandbox Code Playgroud)

当你git checkout通过不是简单分支名称的东西进行任何提交时,Git仍会检出一个提交,但是会将你从任何分支中删除,即,给你一个"分离的HEAD".

我们从上面知道origin/master(现在)提交e05806da9ec4aff8adfed142ab2a2b3b02e33c8c,所以:

$ git checkout origin/master
Run Code Online (Sandbox Code Playgroud)

要么:

$ git checkout e05806da9ec4aff8adfed142ab2a2b3b02e33c8c
Run Code Online (Sandbox Code Playgroud)

都做同样的事情.既然origin/master不是一个地方分支,我结束了:

$ git status
HEAD detached at e05806d
Run Code Online (Sandbox Code Playgroud)

(或有时HEAD detached at origin/master).

因此,git checkout尝试将您提供的名称转换为分支名称是什么. 如果失败,git checkout有这个额外的内置功能:它搜索所有远程跟踪分支,看看是否有一个"大部分匹配"名称.因此git checkout zorg检查名为的本地分支zorg无法找到它,然后在所有远程跟踪分支中搜索匹配的分支zorg.实际上只有一个 - origin/zorg这会触发特殊情况代码.

特殊情况代码简单地实现"创建新的本地分支设置以跟踪相应的远程跟踪分支".也就是说,创建一个本地zorg,其上游(如Git现在调用这些东西)设置为origin/zorg.

请注意,为此,必须有一个合适的远程跟踪分支.如果我根本没有origin/zorg,这将失败 - 如果我有两个,origin/zorg并且thirdrepo/zorg,thirdrepo另一个遥控器在哪里,origin但指向第三个Git存储库,它也会失败,因为Git不知道我的本地是否zorg应该拥有origin/zorgthirdrepo/zorg作为它的上游.

大多数情况下,您只有一个名为的遥控器origin.因此,只要您将所有origin的分支保存为您自己的Git远程跟踪分支存储器,您就可以使用git checkout这些名称来让您的Git创建它们.但有时您会发现必须先运行git fetch,以便更新远程跟踪分支.


小智 24

好吧,我有完全相同的问题,然后我发现在git config中

remote.origin.fetch

不是

fetch = +refs/heads/*:refs/remotes/origin/*
Run Code Online (Sandbox Code Playgroud)

就像是:

[remote "origin"]
  url = https://....
  fetch = +refs/heads/v8.1:refs/remotes/origin/v8.1
Run Code Online (Sandbox Code Playgroud)

将其更改为:

[remote "origin"]
  url = https://....
  fetch = +refs/heads/*:refs/remotes/origin/*
Run Code Online (Sandbox Code Playgroud)

现在'git branch -avv'显示所有远程跟踪分支

如果你想知道我从哪里得到这个奇怪的设置,那是因为我使用了'clone --single-branch'

  • 这解决了我类似的问题,即使我的存储库来自“git clone --depth=1 --no-checkout”。 (4认同)
  • 更改 git 配置文件后,您可能需要执行 ```git fetch --all``` (2认同)
  • 当`git clone`时,您添加了`--single-branch`选项,因此您看不到任何其他分支。你的解决方案绝对是正确的。 (2认同)

Vel*_*uha 6

1)只显示分支:

git branch -r
Run Code Online (Sandbox Code Playgroud)

2) 将远程分支加载到本地 git 中:

git fetch origin/<remote_name>
Run Code Online (Sandbox Code Playgroud)

3)从远程分支创建本地分支(调用它后您可以查看分支到git分支之外):

git checkout -b <remote_name> origin/<remote_name>
Run Code Online (Sandbox Code Playgroud)