git revert 還有這個坑?

最近也是終於開啓了代碼編寫之旅,我只能默默地說一句,寫代碼的感受,簡直不能再爽!java

不過也因爲 git 的分支管理蛋疼懵逼好久,因此必須記錄以及和你們分享一下本次坑爹的旅行。git

寫在前面

每一個公司相比都有本身的 git 分支管理規範,在項目組中開發人員較多的時候,這個就顯得尤其重要。因此咱們必須得掌握 git 的分支管理。基本套路就是有一個主線,而後在迭代週期內,每一個開發人員拉取本身的分支,待開發完畢後你們再 merge 回主線,發佈版本。vim

 
流程圖

具體的 git 代碼分支管理看這個好了:https://nvie.com/posts/a-successful-git-branching-model/服務器

怎麼回事?

到底怎麼就被 git 版本回滾給坑了呢?不急,待我慢慢道來。post

在咕咚的項目組中,在一個新的需求評審完畢,進入開發狀態時,你們會基於 develop 分支拉取本身的分支,命名爲 feature/XXX,而後各自在本身的分支上進行開發。指針

因爲你們開發業務上的不一樣,因此在需求開發完畢,整合代碼的時候,通常都不會出現衝突的狀況,即便出現,那也應該是比較容易解決的。日誌

可在最近的一次 merge 中出現了一個比較奇怪的問題。code

如圖所示:orm

 
1.png

我當前所在的分支是 feature8.29.0_nanchen,該分支已經 merge 了 release8.28.0 分支上的最新代碼,本地沒有任何提交。如今因爲一些緣由,我須要把另一位同事開發的 feature8.28_buyGifts 分支代碼合併到個人分支上。進行開發。開發

意外地出現了不少的衝突。

 
2.png

咱們使用 git status 看看到底發生了什麼。

 
3.png

 

從截圖中能夠看出,git 認爲咱們當前的分支 delete 了很多文件,而這些文件是在 feature8.28_buyGifts 分支上存在的。

咱們 vim 查看文件狀況。這裏就選取第一個 MarketItemsInfo.java 作截圖。

 
4.png

咱們查看其餘衝突文件之後,發現所有是和 Presents 這個類相關的衝突,而這些文件其實是開發 feature8.28_buyGifts 分支的小夥伴開發的,主分支不可能作干預,這裏讓人什麼疑惑。

爲了驗證本身的猜測,咱們查看一下 MarketItemsInfo.java 的提交歷史。

 
5.png

正如咱們所想,確實在 7 個月內,都沒有人動過這個文件。

因此一個 7 個月都沒有人動過的文件,怎麼就會 merge 的時候出現了這個使人費解的衝突呢?

查看一下當前分支全部的日誌。

 
6.png

彷佛發現了一點異常。這位小夥伴曾經往 release8.28.0 進行了 merge 操做,此後被告知未提測不能 merge 到主線的時候,他又對 release8.28.0 分支作了 revert 操做。因此可能所以讓 git 認爲 release8.28.0 上有了這樣的文件修改,由於操做後面被 revert,因此用 git lg <fileName> 的時候,也看不到最近對文件的改動記錄。

我如今只能說多是這個緣由,若是你們有高見的還望留言指導。

若是是這樣,那麼咱們只要在這次 revert 操做以前進行 merge feature8.28_buyGifts 分支代碼的話,應該是不會出問題的。

爲了驗證,咱們從新創建一個分支,而後 reset 到 revert 操做以前,再進行 merge,查看是否還會出現這樣的狀況。

 
7.png

明顯沒有出現任務衝突。

咱們再試試,在 revert 後進行 merge 操做。

 
8.png

如咱們所想,當咱們 reset 到 revert 提交的時候,再進行 merge 直接發生了這個衝突。

這樣的話,必定意義上,已經印證了咱們的想法。git 確實把這個文件當作修改了。

怎麼處理?

遇到了這樣的問題,直觀上,確定是將衝突的改動,所有以這位小夥伴的代碼爲準,由於主線上的代碼,已經確認是沒有人動過這幾個文件的。

最不濟的方法,可能就是直接捨棄掉這個小夥伴的操做,而後強行把他後面寫的代碼,從新寫一遍了(由於他後面的代碼量不多)。

爲何會出現這個 revert 操做?

說到底仍是這次 revert 惹的禍。

我詢問該小夥伴後,得知,他是在 release8.28.0 主分支上 merge 了本身的代碼,而且 push 到服務器後,被告知未提測的代碼不能 merge 到主分支後,但願遺棄 push 到服務器上的這個 merge 操做,因此才採用 revert 命令的。

正確的操做?

我寫這個正確的操做題目,是真的不敢寫的。不過仍是斗膽寫了一下。若是我想遺棄本身 push 到服務器上的提交的話,我必定會選擇 reset 後再進行 push 操做的。

  1. 首先使用 git reset —hard <版本號> 讓 HEAD 指針指向 merge 前的 commit ID。(注意,這是直接放棄以後全部的提交,採用 --hard,這裏由於是沒有別人提交別的代碼)
  2. 再使用 git push origin <分支名> —force 命令強行把提交 push 到服務器便可。

寫在最後

實際上,我本身對 git 的操做也有些模棱兩可,不過仍是但願能用本次教訓給你們簡單作下交流吧。

相關文章
相關標籤/搜索