git clone没有签出活动分支

时间:2011-08-03 14:06:29

标签: git git-branch git-clone git-remote

我有一个远程裸存储库,其中包含两个分支'master'和'testing',其中HEAD指的是'testing'。 当克隆此存储库git检出'master'时,如果'master'和'testing'在同一版本上(即HEAD == testing == master)。 只有当'测试'是一个(或多个)提交落后或提前时,git clone才会检出本地端的'testing'分支。 我在Mac OS X(10.6.8)上使用git 1.7.5尝试了这个。

附录: 我只是尝试使用非裸存储库:

mkdir A
cd A
git init
touch a
git add a
git commit -m "init repo A with a"
git checkout -b testing

现在回到根目录:

cd ..
git clone A B
cd B
git branch -v -a
* master                 28f599b init A
  remotes/origin/HEAD    -> origin/master
  remotes/origin/master  28f599b init A
  remotes/origin/testing 28f599b init A

这是'主人'!回到回购A(我们仍在分支'测试'):

cd ../A
touch b
git add b
git commit -m "add b in branch testing"

现在'测试'是一个提前'提交'。现在让我们再次克隆A:

cd ..
git clone A C
cd C
git branch -a -v
* testing                23bca39 add b in branch testing
  remotes/origin/HEAD    -> origin/testing
  remotes/origin/master  28f599b init A
  remotes/origin/testing 23bca39 add b in branch testing

您可以通过返回A,checkout'master'并将其与'testing'合并来重新验证这种奇怪的行为(以便所有分支具有相同的头部)。现在将A克隆到D中,D将在主人身上检出!

2 个答案:

答案 0 :(得分:1)

git clone复制所有分支及其历史记录,以及SHA1和的引用。 AFAIK refspecs不会被转移,因为它们比git更新(显然),并且克隆协议不保留它们......这意味着它猜测(编辑:这已经被邮件列表确认)。

在克隆期间,通过匹配其SHA1来猜测头部的引用。在您的情况下,SHA1不明确,因为mastertesting都匹配,因此按惯例选择master。据我所知,这没有记录,但应该是。

要查看是这样,请转到B示例回购并运行git ls-remote。输出将为您提供SHA1,而不是refs:

1c3eebcd1bd3659a40f02880918d5fbd5614b51a    HEAD
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/master
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/testing

作为解决方法,

git clone -b <branch_name>

将克隆并签出所需的分支branch_name,例如master或test。

我认为此时你不得不坚持HEAD是master的约定,master是checkout的默认分支,如果你设置了一个不同的开头克隆使用-b开关。< / p>

答案 1 :(得分:0)

从git邮件列表中得到答案 - @Shelhamer:你是对的

  

是的,这是一个已知问题。

     

git协议只发送引用列表及它们指向的对象   至。因此,本地克隆被迫猜测HEAD指向哪个ref。   例如,有类似的东西:

     

28f599b ...... HEAD   1234abc ... refs / heads / master   28f599b ... refs / heads / testing

     

可以看出HEAD可能正在“测试”。但如果它看到:

     

28f599b ...... HEAD   28f599b ... refs / heads / master   28f599b ... refs / heads / testing

     然后它必须任意挑选一个。我们目前的启发式是喜欢的   “掌握”超过其他人,否则按字母顺序选择。所以这是   至少是确定性的,但正如你所注意到的,它并不总是正确的。

     

对此的真正解决方案是扩展git协议以进行传达   符号引用信息(然后等待客户端和服务器)   升级)。过去有些补丁已经浮出水面,但一无所获   它的。也许是时候复活它们了。

     

作为一种解决方法,如果您知道,可以使用“git clone -b testing ...”   提前“测试”是你想要的。

     

请参阅:

     

1。 http://thread.gmane.org/gmane.comp.version-control.git/102039

     

2。 http://article.gmane.org/gmane.comp.version-control.git/113567