「小技巧」使用Git從其他分支merge個別文件
- 2019 年 10 月 3 日
- 筆記
小明發現在實際項目開發過程中,總會遇到各種各樣的情況,比如一個大型的項目或版本迭代可能不是一次上線,可能會分好幾次上線,這時候就會涉及創建多個分支,分別開發。
項目背景
產品經理:我們本次開發三個功能,列表頁功能、詳情頁功能、系統消息功能,分兩次上線,先上列表功能,再上詳情頁和系統消息。
小明:好的吧。
緊接着,小明就將本次需求分為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合併總結的經驗,希望能幫助到大家,僅供參考,有錯誤請指出,謝謝!
歡迎關注微信公眾號」程序員小明」,獲取更多資源。