为什么分支的git签出变得分离?

为什么分支的git签出变得分离?,git,github,Git,Github,这是git show ref的输出: 84cfc856a refs/heads/master 84cfc856a refs/remotes/origin/HEAD 4131d7214 refs/remotes/origin/foo 84cfc856a refs/remotes/origin/master 我有2个本地分支(都是github上的跟踪远程): 主人 福 我知道什么是超然的头脑。 当我执行git checkout foo时,我在分支foo 但当我跑步时: git checkout

这是git show ref的输出:

84cfc856a refs/heads/master
84cfc856a refs/remotes/origin/HEAD
4131d7214 refs/remotes/origin/foo
84cfc856a refs/remotes/origin/master
我有2个本地分支(都是github上的跟踪远程):

  • 主人
我知道什么是超然的头脑。 当我执行
git checkout foo
时,我在分支
foo

但当我跑步时:

git checkout origin/foo

我在超然的头脑中。为什么?

您无法签出远程分支,因为您无法更改它。出于这个原因,git说你处于超然的头脑中,因为你不在回购协议的实际分支中。你可以在那里,但你是超然的

要签出本地没有的远程分支,只需键入

git checkout foo

git将自动创建一个跟踪远程分支的本地分支。然后你才能开始做事情。

考虑以下情况:在某个时候,你已经将远程分支
源/foo
签出到你的工作副本中,正在创建一个本地分支
foo
。这通常是由

git checkout foo
现在让我们假设
foo
指针(您确实记得,所有分支实际上都只是指向特定提交的指针,对吗?)指的是提交
A

现在,您已经完成了一些工作并将其提交到该分支(在提交
A1
下)。然后再做一些工作。然后再来一些。因此,现在您的本地
foo
分支指向提交
A4

local foo: A4 -> A3 -> A2 -> A1 -> A
同时,其他人也做了一些工作,并将其推送到远程存储库
foo
。无论是某种合并,还是直接提交,都无关紧要;真正重要的是,远程foo历史现在看起来如下:

origin/foo: A4' -> A3' -> A2' -> A1' -> A
现在您决定实现您的本地分支(例如,为git push做好准备)。最自然的方法是调用
git pull origin foo
命令,这将创建一个合并提交,它将“统一”两个分支:

git pull origin foo后的本地foo:

   A4 -> A3 -> A2 -> A1 -
  /                      \  
A5 (merge commit)         A
  \                       | 
   A4' -> A3' -> A2' -> A1' 
但是,让我们说,在这个时刻,完全合并这些分支并不是一个明智的解决方案。例如,您必须在您的计算机上测试远程
foo
的当前状态,并且/或者将有许多合并冲突,您不确定如何更好地解决

因此,您真正需要的只是在不更改现有本地同名分支的情况下,拥有远程
foo
当前状态的本地副本。这正是git checkout origin/foo的用途

现在,在理想的情况下,
git
应该为这个提交创建一个合理的分支名称(当它签出时)。唯一的问题是,选择什么名字?它绝对不应该是
foo
——记住,如果您想替换/更新该分支,您可以使用其他方法。而其他名字则是名字崩溃的潜在来源

所以这里发生了什么:一个分离的“无分支”头部被创造出来。现在由您决定如何处理它:您可以快速测试更改,并将其合并到本地
foo
分支中,就像前面所示(即使已分离,HEAD现在也会指向具有其自身历史记录的常规提交),或者,如果您需要做一些工作,可以在其顶部使用

git checkout -b origin_foo 
。。。选择您认为适合此提交的任何名称

TL;DR-
git checkout origin/foo
git pull origin foo
不同。他们都有自己的理由被使用