繁体   English   中英

在 Git 中,我可以“签出”本地仓库中的所有远程分支吗?

[英]In Git, can I “Checkout” all remote branches in my local repo?

我们重新创建了我们的 Gitlab 服务器,我正在推送我检查过的分支。 然后我注意到我仍然可以检查我从未接触过的 repo 中的所有其他分支。 但是,当我尝试将所有分支推送到新的 Gitlab 服务器时,它只推送了我签出的分支,而不是列出的所有分支。 有没有办法签出所有分支或将这些分支推送到服务器?

如果你跑

git branch -r

然后你可以看到远程分支。 如果你把所有这些都放到一个文件中,然后把

git checkout 

作为所有记录的前缀(使用 vim 这很容易做到),然后在命令行中运行您的文件,然后它应该checkout所有分支。

然后我注意到我仍然可以检查我从未接触过的 repo 中的所有其他分支......

为了获得正确、彻底的答案,我们需要注意两点:

  1. git checkout可以签出一个分支。 这里不足为奇(嗯,还没有)。 执行此操作时,Git 会检出分支。 这涉及检查一个特定的提交,但也将您“置于”分支上,以便git status表示,例如, on branch master

  2. git checkout可以检出分支的东西。 例如,当您使用git checkout v2.1 (其中v2.1是标签名称)时, Git 会签出一个特定的提交,并将其称为分离的 HEAD

    当您处于此分离的 HEAD 模式时,您不在任何分支上。 正如我们稍后将看到的,这个分离的 HEAD 事物也适用于其他非分支名称项目,包括远程跟踪名称,如origin/master

我们在这里真正需要的是一个好的、可靠的词分支定义。 不幸的是,在 Git 中,有多个相互冲突的定义,具体取决于您喜欢如何使用这个词。 (有关此的更多信息,请参阅“分支”到底是什么意思?

我们在上面第 1 项中使用的含义是一个分支名称,有些人称之为本地分支 这些是masterdevelop之类的名称(相对于origin/masterorigin/develop )。 像这两个分支名称(实际上只是较长形式的简写,此处为refs/heads/masterrefs/heads/develop )具有两个重要属性:

  • 它包含一个提交的 hash ID,并且
  • Git 将在各种条件下自动更新存储在该名称中的 hash ID。 特别是,当在“打开”您的一个分支时进行新提交时,Git 会将提交的 hash ID 存储到分支名称中。

这些分支名称存在于您的存储库中,并且完全独立于任何其他存储库中可能存在或不存在的任何分支名称。

origin/masterorigin/develop等名称并不完全是分支名称,尽管有些人喜欢称它们为分支名称。 1 (这是 Git 和 Git 用户使用的相当不稳定的定义导致问题的地方。)他们遵守第一条规则——它们指向一个特定的提交——但不是第二条。 2您可以运行git checkout origin/master ,但与标签v2.1一样,您最终会得到一个分离的 HEAD。 你不在任何分支上。

所以这可能是整个答案:

  1. git checkout branch您已经拥有的(本地)分支,并且
  2. git checkout remote-tracking-name签出由远程跟踪名称标识的提交。

但这不是完整的答案,因为git checkout可以为您创建一个分支。 3假设您没有名为develop的本地分支,有一个远程跟踪名称origin/develop 跑步:

git checkout develop

通常会成功,并且首先使用origin/develop创建一个(本地) develop来设置其上游和当前提交 hash ID。 4即 Git 会先寻找已有的分支名称develop 如果确实存在, Git 将(尝试5 )检查该分支,然后完成。 但如果没有,而不是立即失败,Git 会四处寻找,看看您是否有一个看起来相似的远程跟踪名称,例如origin/develop 如果是这样,结帐使用 Git 所称的DWIM (按我的意思行事)将其转换为git checkout -b develop origin/develop

因此,对于上述两个,我们必须添加:

  1. git checkout name-that-does-not-yet-exist如果可以,将创建一个分支并检查它。 “DWIM”功能会找到一个远程跟踪名称以用作指导,并创建分支并将其签出。

1请注意,远程跟踪名称origin/masterorigin/develop也缩写为 forms,分别用于refs/remotes/origin/masterrefs/remotes/origin/develop 如果您不小心创建了一个名为origin/X本地分支,它的全名是refs/heads/origin/X ,这就是使它成为本地分支的原因。 但是,您应该快速重命名或删除它,因为 Git 会将其缩短为origin/X ,这可能会让您感到困惑,特别是如果您还有refs/remotes/origin/X , Git也会缩短为origin/X

2 Git确实更新了远程跟踪名称,但是当您运行git fetch时它会这样做。 您的 Git 调用其他一些 Git - 例如,在origin那个- 并要求develop提交每个分支名称,在这种情况下是master和 development ,识别。 如果需要,您的 Git 然后会获取这些提交。 如果你已经有这些提交,你的 Git 可以跳过这一步。 然后,使用存储库中本地可用的提交,的 Git 现在创建或更新与其他 Git 中的分支名称相对应的远程跟踪名称。

由于您不能“启用”远程跟踪名称,因此在git fetch时间更新这些名称是安全的。

3其实它有很多create-a-branch模式,使用git checkout -b , git checkout -B , git checkout --track ,等等但在这里,我们只关注 Git 所称的“DWIM”。

4其中一些是可配置的。 此处的描述仅涵盖默认操作,以防止此答案更长。

5 git checkout有时会因错误而失败,在这种情况下,它应该不理会所有内容。 错误消息旨在告诉您为什么它什么也没做。


结论

除了以通常的方式检出本地分支外,还有两种方法可以git checkout “远程分支”——无论你所说的“远程分支”是什么意思——因为你可以使用分离 HEAD 模式检出,从而检查, origin/foo ,或者您可以使用 DWIM 模式使用origin/foo创建本地foo ,并以通常的方式将其作为本地分支检查。

如果你确实使用 DWIM 模式,你会积累一堆新的本地分支。 完成后,这些就是您的分支名称。 另一个Git 发生问题时,它们不会自动更新。 它们只会在您“开启”它们并执行更新它们的操作时更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM