問題是git commit --amend 引發的。 一條commit已經push到遠端develop了,可是後來又在這條commit上進行了amend操做,致使這條commit的哈希碼發生了變化。而且後續又在這條commit以後進行了N條commit操做。java
<Begin>git
大概的狀況畫了個簡圖,如圖所示。下面的綠色就是最後相同的地方,紅色的那條作的是相同的功能message是同樣的,可是提完develop以後又改動了不少而後使用amend擠壓了。xcode
這個時候比較頭疼了,由於那條amend的commit裏面是發生了太多改動,我採用的是能夠避免衝突的方法,可是會改develop的commit樹安全
git checkout develop git reset 2c4532 //上面97,98,99的改動會被放出來 git stash //先把這些改動存起來 git reset --hard 5d67bc //等因而把96徹底剔除了,代碼回到了95的狀態 git cherry-pick 8a6f7f //把那一條修改後的功能commit(96的feature)粘貼過來,這一步100%不會有衝突 git stash pop //把以前存起來的那些改動再放出來,這一步不能保證100%無衝突,但實際因爲兩個功能模塊離得比較開,因此也沒有發生衝突。 git add . git commit -m " " //把develop上面的97,98,99三條commit 擠壓成了一條後commit git cherry-pick 86f6cc d34c7 2817f5 //這一步把feature分支的97,98,99三條commit粘貼過來,由於這三條基本是基於8a6f7f開發的,因此也沒有發生衝突。 董鉑然博客園
<End>spa
這樣改完以後develop的commit樹如上圖所示(第97條就是把以前的97,98,99擠壓成的1條),能夠編譯經過功能都能實現。 可是缺點是這時候須要強推develop了。3d
組裏另外一我的提出的解決方案是code
<Begin>(圖再貼一遍 省的往上翻)blog
git checkout feature //操做都在feature分支進行,不動develop的代碼 git reset 5d67bc //把feature分支上「不科學」的commit 96,97,98,99 所有放出來 git stash //所有臨時存起來 git rebase develop //快進一下,合入了全部develop的新代碼 100%無衝突 git stash pop //把以前揉在一塊兒的4條commit的代碼一塊兒放出來,這時候會有大量衝突。 git add . git commit -m "fix" //解決衝突後commit一下 //而後再把最後的一條commit merge入develop,最後的結果時develop以下
<End>開發
能夠看出這種作法,不須要強制push develop的代碼。理論上更加科學,可是中間須要解決大量的衝突。博客
過後檢討一下,以爲兩種方法其實各有優劣,若是組內成員很少,能夠在你們的監督下 完成強推develop的操做。 由於解決了大量衝突可能會比 很是清晰瞭解差別後-f強推develop更容易出現錯誤。 固然若是是大型項目,幾十人團隊,而且遠端都綁上了編譯檢查,和merge規則的項目也只能使用第二種方法了。
對於一個碼農而言,比寫出bug更恐怖的是把代碼弄丟了或弄亂了。 對於這種問題也是有一種統一的解決方案
①.git reset --hard 哈希碼 , 這條很是廣泛,若是出現問題有點亂直接回到一個安全的commit
②.git reflog 對於有rebase或merge這種操做,第一條指令就用不了了,由於被污染的並不只僅是最後一條commit。 這時要用這個萬能恢復指令,回到一個操做的哈希碼。
③.可是前兩種方法都是對於一些已經加入過git的代碼進行恢復。 若是一些代碼尚未commit 這時候弄丟了 那些指令就都幫不了你了。 這時候只能看IDE有沒有local history了。(local history至關於IDE幫你實現了一個相似於git的功能)以前就有過一次第3種狀況的經歷,當時是把沒commit的代碼給reset了 使用localhistory得以恢復。好在如今iOS的xcode 和 Android的Android Studio都是有local history的,
若是上文說的問題有更好的解決方案,也歡迎一塊兒討論。