2011-08-03 59 views
3

我有一個遠程裸倉庫,有兩個分支'master'和'testing',其中HEAD是指'測試'。 如果'master'和'testing'在同一個版本(即HEAD == testing == master)上,克隆這個存儲庫時,git檢出'master'。 只有當'testing'是一個(或多個)提交落後或提前時,git clone會檢出本地的'testing'分支。 我在Mac OS X(10.6.8)上用git 1.7.5試了一下。git clone不簽出活躍的分支

附錄: 我只是試圖用非純倉庫一樣的:

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" 

現在'測試'是一個提前'主'。現在,讓我們一個重新克隆:

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,結賬「主人」重新驗證這種怪異的行爲,並用「測試」(使所有分支具有相同頭)合併。現在將A克隆到D和D將在主服務器上檢出!

+0

我看着'GIT中LS-remote'輸出和相信我發現根的說明中,短通過git來源閱讀現在。由於克隆傳輸協議,活動分支由'HEAD'的SHA1確定,而不是refspec,而在含糊不清的情況下缺省爲'master',如帶有共享HEAD的兩個分支。 – shelhamer

回答

0

得到了來自git的郵件列表的答案 - @Shelhamer:你說得對

沒錯,這是一個已知的問題。

git協議只是發送refs列表和它們指向 的對象。所以本地克隆被迫猜測HEAD指向哪個頭部。 例如,喜歡的東西:測試

就可以看到頭可能是 「測試」

28f599b ... HEAD 1234abc ......裁判/頭/主 28f599b ......裁判/頭/。但是,如果它認爲:

28f599b ... HEAD 28f599b ......裁判/頭/主 28f599b ......裁判/頭/測試

那麼它選擇一個任意。我們目前的啓發式是比其他人更喜歡 「主人」,否則按字母順序選擇首字母。所以它至少是確定性的,但正如你注意到的那樣,它並不總是正確的。

真正的解決方案是擴展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

1

git clone複製所有分支及其歷史記錄,以及SHA1和而不是的參考文獻。 AFAIK refspecs不會被轉移,因爲它們比克隆更新(明顯),克隆協議不保留它們......這意味着它猜測(編輯:這已經被郵件列表確認)。

在克隆期間,通過匹配其SHA1來猜測頭的ref。在你的情況下,SHA1是不明確的,因爲mastertesting都匹配,因此按慣例選擇master。這在我所知的任何地方都沒有記錄,但應該是。

要看到這是如此,請轉至B示例回購並運行git ls-remote。輸出會給你SHA1s,而不是裁判:

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

作爲一種變通方法,

git clone -b <branch_name> 

將克隆並檢出你想要的分支branch_name,如船長或測試。

我認爲在這個時候你不得不堅持這個約定,HEAD是master,master是checkout的默認分支,如果你設置了一個不同的頭部供devs克隆使用-b開關。

+0

感謝您的快速回復,但這不是問題。要麼我錯過了什麼,或者這是一個混帳錯誤。如果git檢出了HEAD的引用,它應該在分支頭相同的情況下執行。 – Udo

+0

感謝您使用更多信息更新您的問題,現在更清楚。我已經轉載了這個行爲。這不是特定於OS X上的git,因爲它也是ubuntu natty獨角鯨的行爲。 – shelhamer