为什么分支的git checkout变得分离?

时间:2014-04-02 21:02:08

标签: 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上跟踪遥控器):

  • FOO

我知道什么是独立的HEAD。 当我git checkout foo时,我在分行foo

但是当我跑步时:

git checkout origin/foo

我是独立的HEAD。为什么?

2 个答案:

答案 0 :(得分:2)

您无法签出远程分支,因为您无法更改它。出于这个原因,git说你处于独立的HEAD中,因为你不在你的repo的实际分支中。你可以在那里,但你是超然的。

为了结帐您不在本地的远程分支,只需输入

git checkout foo

并且git将自动创建一个跟踪远程分支的本地分支。只有这样你才能开始做事。

答案 1 :(得分:0)

请考虑以下情况:在某些时候,您已将远程分支origin/foo签出到您的工作副本中,并在进程中创建本地分支foo。这通常仅仅是......

git checkout foo

我们现在说foo指针(你确实记得所有的分支都只是指向特定提交的指针,对吧?),提到了commit 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 - 记住,如果你想要替换/更新那个分支,你还有其他方法可以做到这一点。其他名称是名称崩溃的潜在来源。

所以这里发生了什么:一个分离的 - '无分支' - HEAD被创建。现在由您决定如何处理它:您可以快速测试更改并将其合并到您的本地foo分支中,如前所示(因为即使是分离,HEAD现在指向具有自己历史记录的常规提交) ,或者,如果您需要做一些工作,请在其顶部创建一个本地分支...

git checkout -b origin_foo 

...选择您认为适合此提交的任何名称。

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