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

时间:2019-10-24 18:25:38

标签: git gitlab

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

2 个答案:

答案 0 :(得分:0)

如果您运行

git branch -r

然后您可以看到远程分支。如果您将所有这些文件都放入文件中,然后放入

git checkout 

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

答案 1 :(得分:0)

  

然后我发现我仍然可以检出我从未接触过的回购中的所有其他分支...

要获得正确,彻底的答案,我们需要注意两件事:

  1. git checkout可以签出分支。这里不足为奇(嗯,还没有)。执行此操作时,Git检出分支。这涉及检出一个特定的提交,还使您“进入”分支,以便git status这样说,例如on branch master

  2. git checkout也可以 检出不是 分支的内容。例如,当您使用git checkout v2.1(其中v2.1是标记名)时,Git签出一个特定的提交,并调用分离的HEAD

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

在这里,我们真正需要的是对 branch 一词的良好定义。不幸的是,在Git中,有多个冲突的定义,具体取决于您喜欢使用该词的方式。 (有关更多信息,请参见What exactly do we mean by "branch"?

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

  • 它包含一次提交的哈希ID,并且
  • Git将在各种情况下自动更新该名称中存储的哈希ID。特别是,当 you 在分支中的一个分支上进行新提交时,Git会将 new 提交的哈希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的本地分支,但 do 有一个远程跟踪名称origin/develop。正在运行:

git checkout develop

通常会成功,并且将首先使用develop 创建一个(本地)origin/develop来设置其上游和当前提交哈希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也是缩写形式,分别为refs/remotes/origin/masterrefs/remotes/origin/develop。如果您不小心创建了一个名为origin/X local 分支,则其全名是refs/heads/origin/X,这就是它成为本地分支的原因。不过,您应该快速重命名或删除它,因为Git会将其缩短为origin/X,这很可能使您感到困惑,特别是如果您还有refs/remotes/origin/X时,Git也将 缩短为origin/X

2 Git 确实更新远程跟踪名称,但是在运行git fetch时会这样做。您的Git调用了另一个 other Git(例如origin上的一个),并要求那个 Git提交每个 >分支名称masterdevelop可以识别。然后,如果需要,您的Git将获得那些提交。如果您已经有了这些提交,则您的Git可以跳过此步骤。然后,利用您的存储库中本地可用的提交,您的Git现在可以创建或更新与另一个Git中的分支名称相对应的远程跟踪名称。

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

3 实际上,它有很多创建分支的模式,使用git checkout -bgit checkout -Bgit checkout --track等。但是这里我们只看Git所说的“ DWIM”。

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

5 git checkout有时会因错误而失败,在这种情况下,它应该让一切都消失了。该错误消息旨在告诉您为什么它什么也不做。


结论

除了以通常的方式签出本地分支机构外,还有两种方式可以git checkout“远程分支机构”(无论您指的是“远程分支机构”)是因为可以使用分离的HEAD模式检出origin/foo并进行检查,也可以使用DWIM模式使用foo创建本地origin/foo并将其检出为本地分支以通常的方式。

如果您使用DWIM模式,则会积累一堆新的本地分支。完成此操作后,这些就是您的 分支名称。当 other Git中发生某些事情时,它们将不会自动更新!它们只会在您“启用”它们并执行一些更新操作时更新。