2014-01-17 55 views
2

我想知道如果我創建的Git分支具有相同的名稱作爲一個遠程分支會發生什麼。一旦我推動我的分支,第一個分支會停止在遠程存儲庫中存在嗎?例如,可以說我克隆純倉庫以下重用的Git分支名稱

master A----B---C 
       \ 
mybranch   D---E 

然後我繼續創建一個從稱爲mybranch分支,產生了幾提交。我知道,如果我籤mybranch跟蹤分支將被創建,但如果我創建一個分支(的Git分支mybranch),一旦我決定要推mybranch會發生什麼?我做了一些例子,但我無法弄清楚發生了什麼。謝謝。

+0

你有沒有試過將分支推送到遠程? – Miller

回答

1

所以在您的特定例子中,你會基於凱明C上創建一個提交F和具有本地分支mybranch指向該承諾,創造了以下情況:

mybranch     F 
         /
master   A----B---C 
         \ 
origin/mybranch   D---E 

如果您想嘗試推該分支/提交到在上游mybranch,GIT中會拒絕推因爲它是mybranch的非快進更新。

您當地的分行恰好具有相同的名稱作爲上游分支不來這裏發揮作用的事實。上游的Git不關心或不瞭解你的本地分支名稱(如果有的話,甚至有一個名字;推動什麼可能是一個無名的分離頭)。

+0

我再次完成了這個例子,我肯定從git那裏得到了一個警告。大!不知道第一次嘗試時發生了什麼。 – rjss

1

「TL; DR」總結:它確實有效,但它可能會混淆,所以你可能應該重新安排你的分支名稱。下面是Magnus Bäck's answer的擴展版本。


這裏涉及兩個實體(或更多,如果你有一個以上的遠程,但我們堅持兩個:-),你和origin):

  • 自己的回購和
  • 「the」remote。

有曖昧refname(見gitrevisions影響「自己回購」,因爲遠程都有自己的名字,在自己的.git目錄。此外,當你在一個refname型,讓你的Git命令解決這個問題,它根據gitrevisions列出這些規則解決。

這仍然不是一個偉大的情況,因爲它可以混淆挫折感的。此外,「只會影響你」也許是誇張或「善意的謊言」,因爲當你使用git push,有很多的選擇:

  • 你可以git push origin mybranch:newbranch。這告訴你的git查找名稱mybranch(用通常的解決方法,在Magnus Bäck's answer中獲取提交F),然後聯繫origin並要求它更新或甚至在其一側創建名爲newbranch的分支。

  • 您可以git push origin mybranch。這會告訴你的git像往常一樣查找名稱mybranch,但是請聯繫origin並要求它更新或創建一個名爲mybranch的分支,該分支(如前所述)不會快進,並且會被拒絕。

  • 您可以git pushgit push origin,它會查找您的push.default設置。 如果設置爲currentmatchingsimple,git確實希望您的名字與遠程名稱相匹配。如果它設置爲nothing,git要求您每次提供「其他方名稱」。如果設置爲upstream,那麼git使用「上游」名稱,它不需要匹配本地名稱。

因此,upstreampush.default設置幾乎意味着這種情況:不一定是曖昧的名字,但如果你的名字,mybranch,從名稱不同的遙控器上的任何情況下,newbranch

(還有什麼用git fetch發生的問題。見下文腳註3.額外信息)


由於歷史的原因,或者只是被討厭的git checkout命令解析分支名稱用不同的規則。我實際上並不知道爲什麼,但至少在可預見的將來,我們會堅持下去。

設置設置/更改/檢查git configpush命令還檢查remote.origin.push,如果設置的話,甚至branch.mybranch.pushremote,如果的設置。如果你配置了很多配置設置,這會非常混亂!假設您不要將自己設置爲怪異的角落。

「上游」通過組合branch.name.remotebranch.name.merge找到。例如,您可以將branch.mybranch.remote設置爲originbranch.mybranch.mergenewbranch。那麼mybranch的「上游」名稱是origin/newbranch。因此,push.defaultupstream設置讓git push自動解決,mybranch推到newbranch在遠程origin。這個相同的「上游」配置自動與git fetch一起工作。

因爲涉及到兩個實體,所以當git fetch超過origin的分支名稱時,需要將它們從您自己的分支名稱中分離出來。這樣做的方式是從遠程倉庫獲取所有分支名稱,然後在它們前面插入文本:分支master在遠程origin上成爲本地參考名稱refs/remotes/origin/master您的分行進入refs/heads/name; 他們的分支進入refs/remotes/origin/name;並且這兩個名稱空間保證不會相互碰撞,因爲heads/remotes/是不同的。

有一個配置條目 - 不要改變這個特定的一個,除非你知道你在做什麼;它真的只是在那裏,使鏡子可以工作不同 - 說:

remote.origin.fetch = +refs/heads/*:refs/remotes/origin/* 

這樣做。這就是上的mybranch首先變爲origin/mybranch,並且當您輸入名稱origin/mybranch(同樣是因爲gitrevisions中的規則),該規則將翻譯成完整的,從不含糊的名稱refs/remotes/origin/mybranch,然後名稱爲期望的提交。