2009-09-25 78 views
9

我試圖把我的(第一次!)混帳回購協議是這樣開始:爲什麼「git push helloworld + master:master」而不是「git push helloworld」?

$ git push helloworld 

但我得到這個回:

To [email protected]:helloworld.git 
! [rejected]  HEAD -> master (non-fast forward) error: 
failed to push some refs to '[email protected]:helloworld 
git' 

所以我發現another StackOverflow question關於「修訂提交」,並嘗試了建議從那裏不知道它是否會幫助我:

[email protected] /c/test/helloworld (master) 
$ git push helloworld +master:master 

它的工作!

但我不知道爲什麼它固定我的問題:(

有人能解釋爲什麼這個工作,但「git push helloworld」不?

+1

針對您的評論添加了另一種解決方案。 – VonC 2009-09-25 06:41:54

回答

18

您似乎改寫自己的歷史記錄(SHA-1 。您的提交)在你的主分支

這意味着,你可以不再推快進模式

的+主力對應的推送發生:
通過有可選的前導+,你可以告訴git更新<dst>裁判,即使更新不是快進。

注意:如果其他人已經克隆了您的存儲庫,這可能會很糟糕,因爲他們將不再能夠在沒有衝突的情況下拉動主分支。
另請參閱此SO answer for more


注:如所提到的by Junio C. Hamano

有兩個獨立的安全機制:

  • 發送端安全可以通過重寫 「git push --force」 和/或通過使用一個refspec前綴'+');

  • 接收端安全性可以被您推入的存儲庫的配置變量receive.denynonfastworwards覆蓋。

後者默認爲「不安全」,但是如果安全性在存儲庫中激活,從發送方強制不會停用它。 IOW,兩端都需要同意允許不安全的行爲。


正如Git FAQ提到的,一個可能的行動路線是:

這種情況的最可能的原因是,你需要從遠程先拉。通過首先獲取並檢查日誌,您可以看到遠程端發生了什麼變化。例如,

$ git fetch origin 
$ git log master..origin/master 

將列出所有遠程端有你身邊沒有變化。
如果您需要圖形表示,請使用gitk --left-right master...origin/master
左邊的箭頭是您要推動的更改,右邊的箭頭是遠程端的更改。

其他解決方案(這是你做了什麼):

$ git push origin +branchname 

這將強制更新。如果您沒有權限,那麼有時這會工作:

$ git push origin :branchname 
$ git push origin +branchname 

即遠程首先刪除分支(這通常是允許的),然後重新推「新」(或者倒帶)分支。

被警告,如果您倒帶分支,其他人可能會在拉動時出現問題。
他們可能會合併到分支中,並與您發佈的新分支進行合併,從而有效地保留您試圖擺脫的更改。
但是,它只會是他們的副本,具有不良的修訂。出於這個原因,重繞分支被認爲是輕度反社會的。儘管如此,它通常是合適的。

+0

這是一個私人git存儲庫,只是爲了學習繩索 - 所以我不擔心與他人的衝突。我想要做的是刪除這個存儲庫,並在下次正確執行。我收到「[rejected]」消息後應該怎麼做而不是「+ master:master」? – 2009-09-25 06:31:34

+0

就是這樣。非常感謝!我從零開始重新編寫它,但是這次我首先進行了拉取,然後運行。多奇怪的怪癖!在Mercurial中,我在創建新項目時從來不需要這樣做。 – 2009-09-25 06:52:14

+0

由於相同的原因,hg push有一個強制標誌。如果你改變歷史(通過mq或其他),你將不得不強制推送。 – Dustin 2009-09-25 23:20:43