最近也是終於開啟了代碼編寫之旅,我只能默默地說一句,寫代碼的感覺,簡直不能再爽!
不過也由於 git 的分支管理蛋疼懵逼很久,所以必須記錄以及和大家分享一下本次坑爹的旅行。
寫在前面
每個公司相比都有自己的 git 分支管理規范,在項目組中開發人員較多的時候,這個就顯得尤為重要。所以我們必須得掌握 git 的分支管理。基本套路就是有一個主線,然后在迭代周期內,每個開發人員拉取自己的分支,待開發完畢后大家再 merge 回主線,發布版本。

具體的 git 代碼分支管理看這個好了:https://nvie.com/posts/a-successful-git-branching-model/
怎么回事?
到底怎么就被 git 版本回滾給坑了呢?不急,待我慢慢道來。
在咕咚的項目組中,在一個新的需求評審完畢,進入開發狀態時,大家會基於 develop 分支拉取自己的分支,命名為 feature/XXX,然后各自在自己的分支上進行開發。
由於大家開發業務上的不同,所以在需求開發完畢,整合代碼的時候,一般都不會出現沖突的情況,即使出現,那也應該是比較容易解決的。
可在最近的一次 merge 中出現了一個比較奇怪的問題。
如圖所示:

我當前所在的分支是 feature8.29.0_nanchen,該分支已經 merge 了 release8.28.0 分支上的最新代碼,本地沒有任何提交。現在由於一些原因,我需要把另外一位同事開發的 feature8.28_buyGifts 分支代碼合並到我的分支上。進行開發。
意外地出現了很多的沖突。

我們使用 git status
看看到底發生了什么。

從截圖中可以看出,git 認為我們當前的分支 delete 了不少文件,而這些文件是在 feature8.28_buyGifts
分支上存在的。
我們 vim 查看文件情況。這里就選取第一個 MarketItemsInfo.java 做截圖。

我們查看其他沖突文件以后,發現全部是和 Presents
這個類相關的沖突,而這些文件實際上是開發 feature8.28_buyGifts
分支的小伙伴開發的,主分支不可能做干預,這里讓人什么疑惑。
為了驗證自己的猜想,我們查看一下 MarketItemsInfo.java 的提交歷史。

正如我們所想,確實在 7 個月內,都沒有人動過這個文件。
所以一個 7 個月都沒有人動過的文件,怎么就會 merge 的時候出現了這個令人費解的沖突呢?
查看一下當前分支所有的日志。

似乎發現了一點異常。這位小伙伴曾經往 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,查看是否還會出現這樣的情況。

明顯沒有出現任務沖突。
我們再試試,在 revert 后進行 merge 操作。

如我們所想,當我們 reset 到 revert 提交的時候,再進行 merge 直接發生了這個沖突。
這樣的話,一定意義上,已經印證了我們的想法。git 確實把這個文件當做修改了。
怎么處理?
遇到了這樣的問題,直觀上,肯定是將沖突的改動,全部以這位小伙伴的代碼為准,因為主線上的代碼,已經確認是沒有人動過這幾個文件的。
最不濟的方法,可能就是直接舍棄掉這個小伙伴的操作,然后強行把他后面寫的代碼,重新寫一遍了(因為他后面的代碼量很少)。
為什么會出現這個 revert 操作?
說到底還是此次 revert 惹的禍。
我詢問該小伙伴后,得知,他是在 release8.28.0 主分支上 merge 了自己的代碼,並且 push 到服務器后,被告知未提測的代碼不能 merge 到主分支后,希望遺棄 push 到服務器上的這個 merge 操作,所以才采用 revert 命令的。
正確的操作?
我寫這個正確的操作題目,是真的不敢寫的。不過還是斗膽寫了一下。如果我想遺棄自己 push 到服務器上的提交的話,我一定會選擇 reset 后再進行 push 操作的。
- 首先使用 git reset —hard <版本號> 讓 HEAD 指針指向 merge 前的 commit ID。(注意,這是直接放棄之后所有的提交,采用 --hard,這里因為是沒有別人提交別的代碼)
- 再使用 git push origin <分支名> —force 命令強行把提交 push 到服務器即可。
寫在最后
實際上,我自己對 git 的操作也有些模棱兩可,不過還是希望能用本次教訓給大家簡單做下交流吧。