你真的懂git rebase嗎?

前段時間由于某種原因,開始接手開發公司前端Vue搭建的項目

該前端項目采用的是基于git rebase的形式去合并代碼,而我之前使用git一直都是采用merge的形式合并分支代碼,對于rebase一概不知

故此利用碎片時間學習整理一下關于git rebase的原理以及其和git merge的區別是什么,我會采用實際的案例描述二者的區別

準備工作

  • git 客戶端安裝(只要git bash即可)

  • github上新建一個項目

create project
2
  • 項目clone到本地
3

clone完成以后進入該項目文件夾下,準備工作完畢

模擬日常開發

同學A:

  • 執行git log
4

可以看出此時該項目僅有一次提交記錄

  • 執行新增文件a.txt,并本地提交一次后再次執行git log
5

這個時候打開github,刷新該項目的commit記錄

6

發現遠程倉庫還是只有一次提交記錄的,說明A同學還沒有將自己最新的修改push到遠程倉庫,其他同學這個時候是看不到A的最新提交的

  • A同學將自己的最新提交Push到遠程倉庫
7
  • 再次刷新github 提交記錄,發現已經多了一個A同學提交的最新記錄了
image.png

切分支開發

  • 基于已有兩次提交記錄的本地master分支檢出一個新分支dev,并將該分支推到遠程倉庫
8
  • 查看遠程倉庫,多了一個dev分支
9
  • 此時本地的git分支圖類似如下
10

A同學開發功能

假設A同學基于dev分支開發功能,在本地新做了三次代碼提交,git log
如下


image.png

那么此時的git分支圖如下

image.png
  • 重點

如果此時在A同學準備進行第四次本地提交之前,另一個同學B向遠程倉庫推送了一個master分支的提交,即此時master實際的提交已經向前走了

我們這個時候在github上操作一次commit,模擬另一個同學此時push了master分支

image.png
  • A同學本地更新一下master分支
image.png

發現master分支已經向前走了一次提交,此時的分支圖如下

image.png

此時我們知道A同學開發的dev分支是基于C2提交點切出來的,而這個時候master分支已經被更新了

如果A同學開發完畢,需要將其所作的功能合并到master分支 ,他可以有兩種選擇

直接git merge

如果A同學選擇用git merge的方式進行合并dev到master分支,那么git會這么做

  1. 找出dev分支和master分支的最近共同祖先commit點,即C2

  2. 將dev最新一次commit(C5)和master最新一次commit(C6)合并后生成一個新的commit(C7),有沖突的話需要解決沖突

  3. 將以上兩個分支dev和master上的所有提交點(從C2以后的)按照提交時間的先后順序進行依次放到master分支上

image.png

git rebase 后再git merge

  1. rebase之前需要經master分支拉到最新

  2. 切換分支到需要rebase的分支,這里是dev分支

  3. 執行git rebase master,有沖突就解決沖突,解決后直接git add . 再git rebase --continue即可

此時的git log如下

image.png

可以發現其一并沒有多出一次commit,其二dev后面幾次提交的commit hash值已經變了,包括C3,C4,C5

  1. 切換到master分支,執行git merge dev
image.png

發現采用rebase的方式進行分支合并,整個master分支并沒有多出一個新的commit,原來dev分支上的那幾次(C3,C4,C5)commit在rebase之后其hash值發生了變化,不在是當初在dev分支上提交的時候的hash值了,但是提交的內容被全部復制保留了,并且整個master分支的commit記錄呈線性記錄

其分支圖最終如下

image.png

總結

  • git merge 操作合并分支會讓兩個分支的每一次提交都按照提交時間(并不是push時間)排序,并且會將兩個分支的最新一次commit點進行合并成一個新的commit,最終的分支樹呈現非整條線性直線的形式

  • git rebase操作實際上是將當前執行rebase分支的所有基于原分支提交點之后的commit打散成一個一個的patch,并重新生成一個新的commit hash值,再次基于原分支目前最新的commit點上進行提交,并不根據兩個分支上實際的每次提交的時間點排序,rebase完成后,切到基分支進行合并另一個分支時也不會生成一個新的commit點,可以保持整個分支樹的完美線性

另外值得一提的是,當我們開發一個功能時,可能會在本地有無數次commit,而你實際上在你的master分支上只想顯示每一個功能測試完成后的一次完整提交記錄就好了,其他的提交記錄并不想將來全部保留在你的master分支上,那么rebase將會是一個好的選擇,他可以在rebase時將本地多次的commit合并成一個commit,還可以修改commit的描述等

最后

如果你想要你的分支樹呈現簡潔,不羅嗦,線性的commit記錄,那就采用rebase

否則,就用merge吧

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容