詳解git rebase,讓你走上git大神之路

TechFlow2019發表於2020-11-02

在之前的文章當中我們介紹了git merge的用法,明白了通過git merge我們可以合併兩個分支的改動。這樣我們就可以很方便地進行協同開發了,每個人都在自己的分支下開發程式碼,開發完畢之後再一起合併到master分支。通過這種方式可以保證大家的程式碼不會陷入混亂,但是這樣有一個隱含的缺陷。

缺陷就是我們之前說過的,當我們合併兩個沒有上下游關係的分支時,git會自動替我們生成一個merge commit,記錄此次的merge。記錄merge操作沒有什麼問題,問題是如果我們遇到特殊情況需要反覆merge的時候,就會導致commit的提交記錄非常混亂,你根本分不清什麼是什麼。尤其是當你merge了一個巨大改動的分支之後,你的git log基本上就不用看了,肯定全都是其他人的各種亂七八糟你也不清楚的提交記錄。

為了解決這個頭疼的問題,我們就需要用到rebase操作。

rebase簡介

rebase是一個非常強大的操作,可以實現一些神奇的功能,但是強大也意味著有隱患,因為如果使用得不好可能給團隊的程式碼造成非常大的問題,成為團隊當中被無情指責的背鍋俠。所以我們在使用之前一定要先了解清楚原理,之後再小心謹慎地使用,否則很有可能會產生問題。

首先說說rebase的功能,rebase的功能說白了可以提取我們在A分支上的改動,然後應用在B分支的程式碼上,完成類似於補丁的功能。我這麼說非常空洞,我從learngitbranching.js.org網站上擷取了一些圖,會清晰一些。另外推薦一下這個網站,當中有一些圖形化的演示和實操功能, 我們可以在上面練習我們學到的git命令加深印象。但是它也有一個缺點,就是一些細節介紹得比較少,這也是我沒有一開始的時候就推薦給大家的原因。

這張圖非常經典,是很多場景下的常態。C1是線上的版本,在C1的程式碼上線了之後我們發現了一個bug,於是我們checkout了一個叫做bugFix的分支。與此同時還有新的功能在開發,新的功能提交到了master之後形成了節點C2。這個時候我們在bugFix分支當然可以merge master這沒有什麼問題,但是也可以rebase master,rebase之後整棵git樹會變成這樣:

這個結果就好像是我們先到了C2然後checkout出了bugFix分支,然後在bugFix分支上將之前寫過的程式碼重新寫了一遍。這樣的操作就是變基,當我們rebase了之後再提交合並請求我們的合併記錄裡面會非常乾淨,沒有多餘merge的資訊。對於多人協同開發的場景非常有幫助。

更牛的例子

上面只是一個rebase操作的基本應用,通過rebase操作我們還可以實現更加炫酷的功能。我們來看這樣一張提交圖:

這張圖也非常經典,master是正常的線上分支,在C2節點處程式碼上線。上線之後繼續開發新的需求checkout了新的分支feature,與此同時master也經過了一些合併,合併了另外的一些改動到了C4節點。之後新的分支feature開發完成了一個重要效能提升的改動C5,這時,我們發現了線上程式碼的一個bug並且效能不佳,我們需要緊急修復。於是在C5處checkout了新的分支bugFix,我們在bugFix分支當中修復了bug,想要釋出上線。

這時候feature分支繼續開發到了C6節點,仍然沒有開發完成,也沒有經過系統測試。所以我們並不希望C6的程式碼釋出上線,我們希望合併進入master的程式碼之後C5,C7和C8。我們只需要在bugFix分支rebase到master,然後修復衝突之後提交。提交完成了之後,我們再checkout到master把bugFix分支merge進來。整個流程如下:

git checkout bugFix
git rebase master
git checkout master
git merge bugFix

最後我們得到的結果會是這樣:

我們繼續問一個問題,假如我們只需要合併bugFix分支自己的改動,不希望把C5節點也合併進來,我們應該怎麼辦?如果不用rebase會非常麻煩,我們很難處理。有了rebase之後非常簡單,我們只需要使用onto引數,它可以限制我們rebase從什麼地方開始。

比如我們希望rebase的內容是在bugFix這個分支當中不在feature分支裡的內容,我們可以這麼寫:

git rebase --onto master feature bugFix

git執行這條命令的時候會先找到feature和bugFix的共同祖先,然後將共同祖先之後的部分rebase到master。

還有一個問題是如果我們要把兩個分支合併進master,我們要rebase merge兩次不免有些麻煩,我們也可以這麼操作。比如我們要把剛才說的feature和bugFix都merge進來,我們可以直接執行git rebase master feature,它會先checkout到feature分支然後執行rebase master的操作,之後我們再checkout到master進行合併即可。也就是說我們在命令當中可以把要執行的執行分支和目標分支都寫出來,這樣可以一步到位。

比如我現在在master分支,我執行git rebase master bugFix之後會變成這樣:

比我們自己一條一條命令寫會方便很多。

總結

簡單總結一下,我們使用rebase命令有很多好處,既可以讓merge操作變得順滑,減少沒有意義的commit記錄。也可以實現一些比較棘手的功能,但對於新手來說,這個功能還是比較陌生的,總是會覺得暈不知道自己到底做了什麼。這也是非常正常的,我們可以在learngit這個網站上實際動手試試,多練習一下,這個網站的提交都是虛假的,怎麼玩都不會出問題,總比我們在實際工作當中拿真實的程式碼來演練要好。

在下一篇文章當中我們將會一起來看看git rebase不能做什麼,可能有的隱患。

今天的文章就到這裡,衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,請來一個三連支援吧~(點贊、關注、轉發

原文連結,求個關注

本文使用 mdnice 排版

相關文章