這兩天負責將一個開發了較長時間,代碼量數萬行的C語言項目(A項目)的代碼分支合並到主線。由於之前參與過一些其他項目分支收編時采用git merge引入問題的修改,個人從心理上對git merge有所抵觸。有個動圖形象描述了git merge使用不當帶來的災難:
鑒於上述原因,平時從個人的調試分支向項目公共分支合並commit時一般也采用git cherry-pick的方式(詳見另一篇博客),以盡量保持項目分支在通過gitk查看時是一條直線。原計划此次合入也采用git cherry-pick的方式:先將項目的git log導出到文件中,然后按照下圖利用標記分段的方式過濾出我們項目開發的提交,再通過cherr-pick將這些提交合並到主線。
///begin1 commit xxxxxxxxxx commit xxxxxxxxxx commit xxxxxxxxxx ///end1 commit xxxxxxxxxx commit xxxxxxxxxx ///begin2 commit xxxxxxxxxx commit xxxxxxxxxx commit xxxxxxxxxx ///end2 commit xxxxxxxxxx commit xxxxxxxxxx
。。。。。。
但是由於開發分支歷史上與其他項目的分支進行過多次合並,A項目與其他項目的commit相互穿插,很難進行標記分段;不得已只能采用git merge。既然git merge是最常用的命令而非洪水猛獸,造成問題的最大因素還是人,引入的問題多數因為使用不當。可以通過規范化操作避免問題,自己稍微梳理了下能夠盡量避免問題的操作步驟:
目標:將develop分支上的提交合並到master分支。
步驟:
1.在master分支下執行git checkout -b master_for_merge創建並切換到用於合並的master_for_merge臨時分支;
2.執行命令git merge develop將develop分支的內容合並到master_for_merge分支;
3.直接執行git add .和git commit -m "merge with conflict"兩條命令生成一次提交;
這里需要注意,通常將develop分支合並過來是會產生沖突的,但是不建議現在修改,本來代碼合並過來差異就很大,此時修復沖突如果不慎修改了其他地方引入問題,很難通過代碼比對發現。
4.解決沖突:
在代碼目錄下執行grep -nr "<<<< HEAD" ./找到沖突的地方進行修改,修改完后執行git add .和git commit -m "fix conflict"兩條命令生成一次提交;這樣通過git show HEAD可以清楚的看到我們為修改沖突改了哪些內容;
至此用於合並代碼的master_for_merge分支已經准備好了,為了進一步確認合並沒問題我們再進行兩次校驗。
5.執行git diff master master_for_merge, 確認所有的差異都是develop分支上開發的內容,確認未合入develop分支外的其他內容;
6.執行git diff develop master_for_merge, 確認所有的差異都不是develop分支上開發的內容,確保合入不遺漏;
7.將步驟3生成的"merge with conflict"和步驟4生成的"fix conflict"兩個commit通過git rebase的方式合並為一次commit.
8.測試驗證master_for_merge分支代碼,如果沒問題在master分支下執行git merge master_for_merge就完成代碼合並了.
按上述步驟merge的主要目的是可以通過步驟4,5,6查看沖突解決方式以及進一步確認代碼合入是否有錯和遺漏。
最后,如果可以,建議首選方式還是采用cherry-pick!