Git知識總覽(四) git分支管理之rebase 以及 cherry-pick相關操做

上篇博客聊了《Git知識總覽(三) 分支的建立、刪除、切換、合併以及衝突解決》,本篇博客咱們主要來看一下 rebase 變基相關的操做。rebase 操做和 merge 操做最終均可以達到合併代碼的效果,不過其對分支的影響不一樣。上篇博客中咱們聊到了 merge操做。簡單的說merge操做就是將兩個commit進行合併,而後在這兩個分支合併的基礎上建立一個新的commit。而變基操做簡單的說是改變提交的父類,在改變父類時進行合併操做。合併就可能產生衝突,因此rebase時也會產生衝突,下方會介紹到。html

聊完rebase,下方還聊如何進行cherry-pickcherry-pick的本質其實也是合併,只不過是能夠將任意分支,任意提交合併到相關分支。固然只要是合併操做,都有可能產生衝突,下方會給出cherry-pick操做的基本使用以及如何解決cherry-pick時產生的衝突。git

 

1、merge 與 rebase 的簡單對比ide

下方是咱們作操做以前的分支狀態,共有 bugFix、side 、another 三個分支。如今咱們要作的是分別使用 merge 和 rebase 將分支 side 中的內容合併到master分支。post

  

 

首先咱們先來看一下 merge 操做。上篇博客中已經詳細的聊了merge的相關操做,再次就不作過多的展現了,下方只作了簡單的展現。url

  • 首先切換到master分支
  • 而後在master分支上執行 git merge side 操做,將side分支上的內容合併到master分支上。
  • 最後若是須要的話,在將side分支的指針指向master分支便可。

  

 

而後咱們再看一下 rebase 下的相關操做。spa

  • 首先切換到 side 分支。
  • 而後在 side 分支上執行 git rebase master 操做,將其變基到master分支上。

  

 

 

2、rebase的基本操做3d

首先咱們來看一下在git分支管理中如何使用rebase, 以及rebase的後會起什麼做用。下方會根據一系列的示例來看一下rebase操做的實際效果。首先咱們先來看一下作rebase操做以前的分支狀態,以下所示。目前除了master主分支外,還有其餘三個分支,分別爲bugfix0一、bugfix0二、bugfix03。指針

如今要作的事情是在 bugfix01 的分支上執行rebase操做,將其變基到master分支上。htm

  

 

下方是在 bugfix01分支上執行的 git rebase master 將bugfix01分支變基到master分支上,下方是變基後的分支狀態。從下方的分支中不難看出,以前在 master 分支後方的 bugfix01如今跑到了master分支的後方,而且 bigfix01 分支上的兩個提交(3cc582b、f47d2ac)不見了。取而代之的是基於master分支的兩個新的提交(d6d82d八、14bc685)。這兩個新的提交不但包含了3cc582b、f47d2ac這兩個舊的提交的內容,並且還包含了master分支當前指向的分支(b79aa11)提交上的內容。blog

  

 

上面的表達也許有點抽象,下面咱們能夠話一張圖來表示上述的關係。根據上面的分支關係,簡單的畫了一下上面的 rebase 操做所對應的關係圖。rebase 操做完後,下方畫紅框的分支就被廢棄掉了。而後bugfix01會指向rebase後的commit上。

  

接着上面的操做,能夠切換到master分支,而後執行 git merge bugfix01 命令,將master分支快速移動到bugfix01分支上所指向的內容上。下方就是快速移動後的結果。通過這步後,就完成了一次rebase操做。從rebase操做的結果來看,其對 git 的分支進行了整理,換句話說,rebase操做能夠將其餘分支上的內容合併到主分支上,合併後以前的分支的指針的指向也會隨之變化,變化後以前的提交就會被拋棄掉。

  

 

變基是存在必定風險的,在 ProGit上有一句話:Do not rebase commits that exist outside your repository. 大概意思就是說:不要在你的倉庫在其餘地方存在副本的狀況下,對分支執行變基。也就是說,你從遠程Clone下來代碼,而後對以前的操做進行了rebase, 而且強推到遠端。若是別人也clone的相關倉庫,在其分支上作了相關操做。在push以前執行pull時,由於以前的分支被你rebase了,也就是有了新的提交,在pull時,就會進行merge操做。這樣一來,分支就會更加複雜。若是出現上述問題 就使用rebase 來解決問題,即便用 git pull --rebase 來執行。

這一塊具體的東西仍是參考ProGit上的內容來的比較直觀,在此就不作過多贅述了。

 

3、rebase的衝突解決

爲了看rebase衝突的解決方式,咱們故意的製造了下方的衝突,而後去執行rebase操做。從下方的操做中不難看出,在rebase的過程當中產生了衝突,須要咱們去解決。解決衝突後將相關問題件進行commit, 而後使用 git rebase --continue 操做來繼續rebase。

由於rebase時會合並多個提交,在多個提交合並時會產生多個衝突,全部在一個衝突解決並提交後,進行git rebase --continue繼續合併接下來的點。繼續後仍然有可能產生衝突,產生衝突即解決衝突,直到rebase結束爲止。

 

 

4、cherry-pick的基本操做

接下來咱們來看一下git中比較實用的一個命令:cherry-pick。這個命令的名字是比較形象的,cherry-pick即「摘櫻桃」,使用該命令能夠將任意的commit經過其commit號將其合併到你想要的分支上。接下來咱們就來看一個例子。

下方就演示了cherry-pick命令的使用方法。在 master 分支上,執行 git cherry-pick <一些commit的哈希值> 而後將這些提交合併到master分支上。這些分支會根據cherry-pick的順序進行merge,每次merge都會造成一個新的提交。與rebase命令不一樣,雖然會產生一個新的提交,而以前的提交是不變的。具體以下所示: 

  

 

接下來咱們來看一下具體在終端上cherry-pick的操做命令。下方是目前分支的狀態,而且處於master分支上。如今咱們要作的事情是將 d98ff43  這個commit 拿到master上。

  

 

下方就是咱們執行cherry-pick的命令,以下所示。下方執行cherry-pick時是很是順利的,沒有產生衝突。當提交進行合併時會產生衝突,就不是這個樣子了,稍後會演示到。

  

 

下方就是順利的cherry-pick後的樣子。

  

 

5、cherry-pick的衝突解決

在cherry-pick時遇到衝突是避免的,下方特意搞了一個cherry-pick衝突的例子。爲了更進一步的瞭解衝突的解決方式,下方cherry-pick了多個提交,並且這多個提交在merge時都會有衝突。下方咱們會對這些衝突進行解決。

  • 首先咱們在master分支上經過 git cherry-pick <一系列提交的哈希值>來將 4f8e01九、dbe9e8a、5c52520這三個提交摘到master分支上。
  • 而後咱們會先看到在cherry-pick 4f8e019 這個提交時產生了衝突,報了一個Error:提高不能將cherry-pick命令應用於4f8e019。而且下方給了一系列的提示(解決此錯誤能夠經過正確的方式解決衝突,而後經過git add 或者 git rm將更改的文件進行追蹤,最後可使用 git commit進行提交)
  • 解決一個衝突並commit後,使用 git cherry-pick --continue能夠進一步的進行下一個提交的cherry-pick。下方再次執行git cherry-pick --continue時,又出現了衝突,此刻咱們仍是按照上述的步驟對衝突進行解決,解決完畢後接着git cherry-pick --continue。直到全部的commit被合併完畢便可。具體操做步驟以下所示:

  

 

下方是上述操做的最終結果,cherry-pick了三個commit,衝突了三次,解決了三次。以下所示:

  

 

下篇博客會繼續聊Git的相關的內容。

相關文章
相關標籤/搜索