前段時間由于某種原因,開始接手開發(fā)公司前端Vue搭建的項目
該前端項目采用的是基于git rebase的形式去合并代碼,而我之前使用git一直都是采用merge的形式合并分支代碼,對于rebase一概不知
故此利用碎片時間學習整理一下關(guān)于git rebase的原理以及其和git merge的區(qū)別是什么,我會采用實際的案例描述二者的區(qū)別
git 客戶端安裝(只要git bash即可)
github上新建一個項目
clone完成以后進入該項目文件夾下,準備工作完畢
可以看出此時該項目僅有一次提交記錄
這個時候打開github,刷新該項目的commit記錄
發(fā)現(xiàn)遠程倉庫還是只有一次提交記錄的,說明A同學還沒有將自己最新的修改push到遠程倉庫,其他同學這個時候是看不到A的最新提交的
假設(shè)A同學基于dev分支開發(fā)功能,在本地新做了三次代碼提交,git log
如下
那么此時的git分支圖如下
如果此時在A同學準備進行第四次本地提交之前,另一個同學B向遠程倉庫推送了一個master分支的提交,即此時master實際的提交已經(jīng)向前走了
我們這個時候在github上操作一次commit,模擬另一個同學此時push了master分支
發(fā)現(xiàn)master分支已經(jīng)向前走了一次提交,此時的分支圖如下
此時我們知道A同學開發(fā)的dev分支是基于C2提交點切出來的,而這個時候master分支已經(jīng)被更新了
如果A同學開發(fā)完畢,需要將其所作的功能合并到master分支 ,他可以有兩種選擇
如果A同學選擇用git merge的方式進行合并dev到master分支,那么git會這么做
找出dev分支和master分支的最近共同祖先commit點,即C2
將dev最新一次commit(C5)和master最新一次commit(C6)合并后生成一個新的commit(C7),有沖突的話需要解決沖突
將以上兩個分支dev和master上的所有提交點(從C2以后的)按照提交時間的先后順序進行依次放到master分支上
rebase之前需要經(jīng)master分支拉到最新
切換分支到需要rebase的分支,這里是dev分支
執(zhí)行g(shù)it rebase master,有沖突就解決沖突,解決后直接git add . 再git rebase --continue即可
此時的git log如下
可以發(fā)現(xiàn)其一并沒有多出一次commit,其二dev后面幾次提交的commit hash值已經(jīng)變了,包括C3,C4,C5
發(fā)現(xiàn)采用rebase的方式進行分支合并,整個master分支并沒有多出一個新的commit,原來dev分支上的那幾次(C3,C4,C5)commit在rebase之后其hash值發(fā)生了變化,不在是當初在dev分支上提交的時候的hash值了,但是提交的內(nèi)容被全部復制保留了,并且整個master分支的commit記錄呈線性記錄
其分支圖最終如下
git merge 操作合并分支會讓兩個分支的每一次提交都按照提交時間(并不是push時間)排序,并且會將兩個分支的最新一次commit點進行合并成一個新的commit,最終的分支樹呈現(xiàn)非整條線性直線的形式
git rebase操作實際上是將當前執(zhí)行rebase分支的所有基于原分支提交點之后的commit打散成一個一個的patch,并重新生成一個新的commit hash值,再次基于原分支目前最新的commit點上進行提交,并不根據(jù)兩個分支上實際的每次提交的時間點排序,rebase完成后,切到基分支進行合并另一個分支時也不會生成一個新的commit點,可以保持整個分支樹的完美線性
另外值得一提的是,當我們開發(fā)一個功能時,可能會在本地有無數(shù)次commit,而你實際上在你的master分支上只想顯示每一個功能測試完成后的一次完整提交記錄就好了,其他的提交記錄并不想將來全部保留在你的master分支上,那么rebase將會是一個好的選擇,他可以在rebase時將本地多次的commit合并成一個commit,還可以修改commit的描述等
如果你想要你的分支樹呈現(xiàn)簡潔,不羅嗦,線性的commit記錄,那就采用rebase
否則,就用merge吧