2014-12-04 62 views
4

狀態:學習git。Git重置和強制推送

我做的在兩個系統間

系統1

git reset --hard "SHA Key" 
git push origin master # fails 
git push -f origin master # succeeds 

系統下列2

git pull origin master 

我得到這個消息 「已經跟上時代的。」

系統1中更新/重置的任何原因沒有反映在系統2中的任何原因?

+0

在系統2上,執行'git fetch',然後在兩個系統上比較'git rev-parse origin/master'和'git rev-parse master'。他們都一樣嗎?兩個系統上的 – cmbuckley 2014-12-04 10:22:37

+1

都使用'git branch -vv'來查看跟蹤分支設置。這可能是因爲在其中之一上,'master'跟蹤的是除origin/master之外的其他分支,或者根本不跟蹤。 – GolfWolf 2014-12-04 10:27:24

+0

有關跟蹤分支的更多詳細信息,請訪問:http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches#Tracking-Branches – GolfWolf 2014-12-04 10:28:19

回答

5

原因是你可能倒退了主人。

A --- B --- C --- D 

要這樣:你從這個去

A --- B --- C 

系統2的​​本地master分支仍像第一張圖片,雖然,但從Git的點 ,它包含了所有的歷史主產地的 因爲當地分行已經包含提交A,B和C

我發現,最好的辦法來解釋這是有三種觀點在 混帳:

1)您當地的分支機構。這些是你通常結賬和操作的東西。 2)遠程分支機構。這些是遠程存儲庫上的實際分支。 3)你的本地快照的遠程分支機構。這些是你在 refs/remotes下找到的。它是您上次將它們拖放到 遠程存儲庫上的分支機構的副本。

當你這樣做:

git reset --hard "SHA Key" 

您的影響1),本地主分支。

此:

git push -f origin master 

更新二者2)和3)。我的意思是遠程存儲庫已更新 (refs/heads/master被分配了新的提交)。此外,在本地, refs/remotes/origin/master將被更新以匹配您的推送。

在系統2,本:

git pull origin master 

說任何更新,以獲取遠程主,並將其應用到本地 分支。作爲這個操作的結果,3)也被更新。 refs/remotes/origin/master 現在將指向遠程服務器爲主分支提供的相同提交。 但是,從Git的角度來看,您已經擁有系統 2的所有本地主分支。你恰好有另一個,D, 下降從A,B和C的歷史。換句話說,它現在看起來像是 系統2有一個額外的提交D.Git不會倒帶你的分支,並導致你失去這項工作 - 它不明白,你想讓它在任何地方都不會變成 。它只在立場下(如數學類型)。你有 的修訂,所以你是最新的。順便說一句,這就是爲什麼你會看到有關不強制推送 與其他人共享的分支的警告。復卷大師需要團隊協調, 和一個足夠大的組,它根本不可行。有人不會意識到發生了什麼,並且提交會回來。或者,其他人將承諾在 之間導致他們的推送失敗,並且他們拉,導致有點愚蠢的看起來 歷史,但提交仍然會返回。

如果d導致一個問題,你已經與世界共享,然後 git revert D是一個更好的選擇。它不會遇到這些問題,但它確實意味着你現在已經在你的歷史中有了逆轉。這也意味着 ,D仍然在主設置,這恰好也是一個-D, 撤消它。這有一些其他的含義,但它可能太多而不是 放在這裏,而不是直接關係到你的問題。

此外,如果系統1指向系統2,反之亦然,那麼我很驚訝Git並沒有對你說沒有更新遠程分支或 工作樹。 git push不會更新另一臺機器上的工作樹,並且 不會讓您知道這一點。如果它失敗了,那麼它可能是一個 錯誤。

+0

感謝您的詳細解釋。我得到了大部分。鏈很長 - A - > B - > C - > ------ R - > S我在系統1中從S重置爲C.那麼還原[git revert C]解決方案在這裏?或者是否在這個前進之前要求球隊手動恢復到「C」? – Subramanian 2014-12-04 11:11:02

+0

'git revert C'肯定是你想要的那種情況。 'git reset --hard B'會導致你失去C到S,而且我確信你不需要這個。 :-) – jszakmeister 2014-12-04 11:19:28

0

您將分支的HEAD重置爲較早的提交,然後將其作爲該(主)分支的頭部進行推送。

另一個存儲庫已經有了舊的提交,所以當你做git pull時,這就是爲什麼它說已經是最新的 - 它已經提交了。