小明發現在實際項目開發過程中,總會遇到各種各樣的情況,比如一個大型的項目或版本迭代可能不是一次上線,可能會分好幾次上線,這時候就會涉及創建多個分支,分別開發。
項目背景
產品經理:我們本次開發三個功能,列表頁功能、詳情頁功能、系統消息功能,分兩次上線,先上列表功能,再上詳情頁和系統消息。
小明:好的吧。
緊接着,小明就將本次需求分為2個分支,分別為A、B。
- A:開發列表頁功能
- B:開發詳情頁功能、系統消息功能
原計划:產品經理說先上列表功能,那小明就先開發A分支,列表功能很快開發完成(厲害吧)。
計划有變:風雲變幻,第二天小明按照計划開發B分支,開發到一半,產品經理突然說目前的系統消息功能(位於B分支)比較緊急,需要和列表功能(位於A分支)一起上線,當時小明就懵逼了。趕緊暫停開發詳情頁(位於B分支,雖然已經開發了一部分),轉戰系統消息功能的開發。當系統消息功能開發完成之后,就需要考慮將系統消息功能(位於B分支)和列表功能(位於A分支)放在一個分支上提測(開發一部分的詳情頁功能暫先不需要合並)的問題,這時候分支合並就要派上用場了。
分支合並
說起分支合並,大家第一個想到的命令肯定是git merge ,因為這是分支合並的常用命令。
使用git merge 合並分支會將兩個分支的所有內容進行比較合並,因此我們如果想合並兩個分支中的一部分,顯然直接使用這個命令是行不通的。
So what happens next ? 嘿嘿,有兩種方案可供我們選擇:
強制合並
從其他分支merge指定文件到當前分支,git checkout是個合適的工具。
語法如下:
git checkout source_branch <path>...
我們使用git checkout 將B分支上的系統消息功能添加到A分支上
$ git branch
* A
B
$ git checkout B message.html message.css message.js other.js
$ git status
# On branch A
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: message.css
# new file: message.html
# new file: message.js
# modified: other.js
#
合並完成
但是……
注意:在使用git checkout某文件到當前分支時,會將當前分支的對應文件強行覆蓋
因此,合並A分支上沒有存在的文件沒問題,但是如果合並A分支上原先就存在的文件(比如兩個分支上都對other.js進行過修改),位於分支A上的文件other.js就會被checkout(分支B)過來的other.js覆蓋,導致分支A上之前開發的列表功能付之東流,這樣做肯定是優雅的!
那如何避免同一個文件不強制覆蓋,有沒有更好的解決方案呢(調一下味口)?我們一起來看一下第二種方案。
智能合並
思路:曲線救國,我們通過git merge 強大的分支合並功能來完成此次無縫合並。
- 首先使用
git checkout根據A分支創建一個A_temp分支(避免影響A分支)
$ git checkout -b A_temp
Switched to a new branch 'A_temp'
- 然后將B分支合並到A_temp分支,此時兩個都經修改過的文件會跑出沖突,我們只需解決沖突即可。
$ git merge B
Updating 1f73596..04627b5
Fast-forward
message.css | 0
message.html | 0
message.js | 0
other.js | 1 +
4 files changed, 1 insertion(+)
create mode 100644 message.css
create mode 100644 message.html
create mode 100644 message.js
- 再次切換到A分支,並使用git checkout 將A_temp分支上的系統消息功能相關文件或文件夾覆蓋到A分支,此時可以大膽的覆蓋!因為我們已經在第二步處理過沖突問題。
$ git checkout A
Switched to branch 'A'
$ git checkout A_temp message.html message.css message.js other.js
$ git status
# On branch A
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: message.css
# new file: message.html
# new file: message.js
# modified: other.js
#
-
最后,有強迫症的患者可以卸磨殺驢,把剛剛根據分支A創建的A_temp刪除。
$ git branch -d A_temp
OK,到此分支合並就完結了,現在我們就可以自信地召喚產品經理(我們公司產品兼測試)測試這兩個功能。
擴展
另外給大家介紹一下git merge 使用的小技巧
舉例:要把master分支合並到dev分支
git checkout dev // 切換到dev分支
git merge master --no-ff // 使用--no-ff
默認使用merge命令是ff,即 fast-forward,這種方式從Git 合並歷史中是無法查看到是哪幾個提交對象在一起實現了一個功能。
而--no-ff 標記會在分支合並的時候,創建一個新的提交對象,可以避免丟失master分支的歷史信息,並且把所有的功能疊加在一起提交上去。兩者的區別如下圖所示,大家可以自己體驗一下兩者的區別。
以上就是小明工作中使用git合並總結的經驗,希望能幫助到大家,僅供參考,有錯誤請指出,謝謝!
歡迎關注微信公眾號”程序員小明”,獲取更多資源。
