Git在新克隆的仓库中脱颖而出

时间:2016-07-19 18:47:16

标签: git

我刚刚克隆了一个仓库并试图检查一个分支。分支以分离头模式检出!我不明白为什么要这样做。我刚刚克隆了存储库。

$ git checkout PATCH_branch
Note: checking out 'PATCH_branch'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b <new-branch-name>

HEAD is now at 896c259... xxxxxxxxxxxxxxxxxxxxxxxxxxx

我想也许我可以创建一个本地分支并让它跟踪遥控器。所以我做了:

$ git checkout -b PATCH_branch origin/PATCH_branch
fatal: Cannot update paths and switch to branch 'PATCH_branch' at the same time.
Did you intend to checkout 'origin/PATCH_branch' which can not be resolved as commit?

有人可以解释一下最后一位意味着什么吗?或者为什么我不能在没有分离的情况下结账?我知道在某些情况下我最终会得到一个独立的HEAD,但这不是其中之一。

3 个答案:

答案 0 :(得分:5)

没有origin/PATCH_branch。相反,有一个名称非常差的标记,并且在您的克隆中,您已检出该标记,从而导致分离的HEAD。

为什么会这样?

如果您咨询the gitrevisions documentation,您将看到解析符号引用名称的可能性列表:

  

&lt; refname&gt; ,例如 master head / master refs / heads / master

     

符号引用名称。例如。 master 通常表示 refs / heads / master 引用的提交对象。如果你碰巧同时拥有 heads / master 标签/ master ,你可以明确地说 heads / master 告诉Git你的意思。如果不明确,&lt; refname&gt; 会被在以下规则中进行第一场比赛消除歧义

     
      
  1. 如果 $ GIT_DIR /&lt; refname&gt; 存在,那就是你的意思(这通常只适用于 HEAD,FETCH_HEAD,ORIG_HEAD,MERGE_HEAD CHERRY_PICK_HEAD );

  2.   
  3. 否则, refs /&lt; refname&gt; (如果存在);

  4.   
  5. 否则, refs / tags /&lt; refname&gt; (如果存在);

  6.   

在这种特殊情况下,名称PATCH_branch 实际上不明确,但规则(尤其是我放入粗体文字的部分)仍然适用:如果有一个名为PATCH_branch的标记,并且规则#1和规则#2都无法将名称解析为提交哈希但标记可以,则Git可以检出标记,因此我们不会我需要继续看看规则4,5和6;但无论如何他们在这里:

  
      
  1. 否则, refs / heads /&lt; refname&gt; (如果存在);

  2.   
  3. 否则, refs / remotes /&lt; refname&gt; (如果存在);

  4.   
  5. 否则, refs / remotes /&lt; refname&gt; / HEAD (如果存在)。

  6.   

在这六条规则中,只有一条特定的规则4将给你一个&#34;分离的HEAD&#34;查看。由于你 获得了分离的HEAD,显然规则4不适用。

git checkout

的特殊规则

现在,git checkout有自己的附加&#34;规则4.5&#34;,在某些情况下创建 refs/heads/refname。我相信额外的git checkout规则是您期待在此处体验的规则。

具体而言,git checkout在尝试规则1,2和3 之前甚至,尝试规则4.如果失败,git checkout将会看到它是否可以< em>创建基于仅存在一个匹配的远程跟踪分支的本地分支。在这两种情况中的任何一种情况下,规则4都适用,而git checkout 不会为您提供一个&#34;分离的HEAD&#34;。否则git checkout会返回并从规则1开始。

克隆最初只有远程跟踪分支和标记

您提到这是一个新的克隆,在新的克隆中,只有一个(并且只有一个)远程,默认情况下,您将其所有分支作为远程跟踪分支。如果远程名称为origin(通常是这样),则这些远程跟踪分支位于存储库名称空间的refs/remotes/origin/部分。默认情况下,您还可以获取位于refs/tags/名称空间中的所有远程标记。

git clone的最后一步是git checkout

当你跑步时:

$ git clone <url>

或:

$ git clone <url> <destination>

Git将连接到给定的URL,验证那里有一个Git存储库,向该远程站点询问所有分支和标记的列表,然后在给定的目标目录中为您创建一个克隆存储库(或使用最后一个)用于创建默认目标名称的URL的一部分)。在该存储库中,Git将添加一个名为origin的远程(或您使用-o指定的任何名称)。它会将所有标记复制到您的代码中,并将其分支复制到refs/remotes/origin/远程跟踪分支(如果您指定了不同的-o,请根据需要修改这些名称)。生成的存储库根本没有本地分支

然而,此时,git clone调用git checkout,检查一些分支 - 你告诉它的那个(git clone -b),或者默认情况下,你的Git得到的分支来自遥控器,通常是master。当然,你不能拥有本地master分支机构,这就是我所说的&#34;规则4.5&#34;进来:git checkout看看是否有origin/master,当然还有,所以你的Git创建了一个名为master的新本地分支,跟踪远程跟踪分支{{1事实上,这是你获得origin/master分支的方式!

当你运行master时,你无疑希望Git遵循相同的模式:应该有一个git checkout PATCH_branch,你的Git应该创建一个名为{{的{new(普通,普通,本地)分支1}}基于origin/PATCH_branch(真的是PATCH_branch)。

但相反,你拥有的是一个标签,origin/PATCH_branch。所以特殊的&#34;从远程跟踪分支创建本地分支&#34;规则不适用,并且规则4&#34;的早期应用;也不适用,我们留下了规则1和2(不适用),然后是规则3,这让你得到了#34;分离的HEAD&#34;结帐。

可以创建一个本地分支,但要小心!

回顾六条规则。假设您同时拥有refs/remotes/origin/PATCH_branch refs/tags/PATCH_branch。请注意,规则3通常在规则4之前应用大多数 Git命令会将refs/heads/PATCH_branch视为标记

因为refs/tags/PATCH_branch是特殊的,并且首先应用规则4(而不是在规则3之后),所以您将能够检出本地分支。但是其他Git命令会以你不会期望的方式运行,因为它们将首先应用规则3。

标签名称不佳

标签名称可能不应包含单词&#34; branch&#34;。无论您是否能解决这个问题,都是一个行政问题,而不仅仅是技术问题。找出谁创建了标签及其原因,看看是否可以让项目中的每个人都同意这是一个坏名称,从而删除它。

1 这里的名字无疑令人困惑。本地分支PATCH_branch不是&#34;(远程)跟踪分支&#34;,但它是&#34;跟踪&#34;另一个分支。 远程跟踪分支 git checkout是您的Git本地存储的东西;只要你的Git与他们的Git谈话,它就会自动从Git在master看到的任何内容自动更新。所以你的分支 - 你的origin/master - 是&#34;跟踪&#34;远程跟踪分支origin。所有真正意味着您的master已将origin/master设置为上游,这是一个更新,更好的术语。不过,较旧的Git文档(1.8之前的版本)并没有明确定义上游

答案 1 :(得分:4)

通常,当您git clone存储库时,它只包含一个分支(通常为master,但根据HEAD在原始存储库中引用的内容,可能会有所不同。它还将具有原始存储库所具有的分支的远程引用(这些分支将命名为refs/remotes/origin/branchname)。如果你然后执行git checkout branchname,它将检查refs/remotes/origin/branchname中找到的提交,但由于那不是一个分支(名为refs/heads/branchname),你会得到一个分离的{{1}你不再看分支了。

要解决此问题,您可以按照HEAD向您展示git的消息中给出的建议,实质上在您已签出的提交中创建新分支,或运行您尝试的命令你的第二个上市。第二个命令的警告是,在该命令成功之前,您需要首先返回分支(例如git checkout -b <branchname>)。如果您先运行git checkout master,那么它就会成功。这也将设置新分支以“跟踪”原始分支,因此您可以使用它来git checkout -b <branchname> origin/<branchname>git push等。

答案 2 :(得分:0)

您正在使用checkout而不是clone来获取存储库(您可以简单地跳过问题的克隆部分)。

您的仓库似乎没有任何远程存储库可以检出。什么是git remote -v的输出?

它可能应该是名为origin的同一个远程存储库,一次用于获取,一次用于推送。如果您没有,则应git remote add <remoteRepo>