1. 程式人生 > >git rebase(變基)—— Git 學習筆記 19

git rebase(變基)—— Git 學習筆記 19

git rebase(變基)

認識 git rebase

假設你現在基於遠端分支"origin",建立一個叫"mywork"的分支。

$ git checkout -b mywork origin

在這裡插入圖片描述

現在我們在 mywork 分支做一些修改,生成兩個提交(C5和C6).

在這裡插入圖片描述

但是與此同時,有些人也在"origin"分支上做了一些修改並且做了提交了。

你可以用"fetch"命令把"origin"分支上的修改拉下來(但是不合並); 正如下圖,"origin"和"mywork"這兩個分支“分道揚鑣”了。

在這裡插入圖片描述

你可以用"merge"命令把"origin"分支合併到你的分支,這會生成一個合併提交(C7)。
在這裡插入圖片描述

但是,如果你不喜歡分叉與合併,你想讓"mywork"分支的歷史看起來像一條直線,那你可以用 rebase命令

$ git checkout mywork
$ git rebase origin

這會把分叉之後的"mywork"分支(C5,C6)“嫁接”到“origin”分支的頂端。如下圖:
在這裡插入圖片描述

當“mywork”分支更新之後,它會指向最後一個新建立的提交(C6’). 而那些老的提交(C5,C6)會被Git 的垃圾收集機制丟棄,如下圖:

在這裡插入圖片描述

我們可以看一下用 merge 和用 rebase 所產生的歷史的區別:

在這裡插入圖片描述

理解 git rebase

之前我們說過git cherry-pick

命令(可以參考我的博文git cherry-pick 詳解).

其實“git rebase”就是一系列的“cherry-pick”,只是這一系列的動作用一條命令(git rebase)給完成了。你完全可以通過多次手動“cherry-pick”來複制其行為(不過不太方便,更容易出現人為錯誤)。

假設你要把 topic 分支 rebase 到 master 分支上

D <-- topic(*)
|
| C <-- master
B |
|/
|
A

你會執行命令:

git checkout topic
git rebase master

在上面的上下文中,“git rebase master”這條命令的潛臺詞是:

  1. git checkout master # 切換到master分支

  2. git checkout -b topic_rebased # 基於master分支建立並切換一個新分支,比如叫 topic_rebased

  3. for each commit C in master…topic # 對於在topic分支且不在master分支的每個提交 C

    ​ git cherry-pick C # 揀選 C 到 topic_rebased 分支

  4. 忘記"topic" 的過去, 把 topic_rebased 改名為"topic"

過程如下圖:

D <-- topic(*)
|
| C <-- master
B |
|/
|
A
D <-- topic
|  
| C <-- master, <--topic_rebased(*)
B |
|/
|
A
   B' <-- topic_rebased(*)
D  |
|  |
|  C <-- master
B /
|/
|
A
   D' <-- topic_rebased(*)
   |
   B'
D  |
|  |
|  C <-- master
B /
|/
|
A
D' <-- topic(*)
|
B'
|
C <-- master
|
A

在 rebase 的過程中,也許會出現衝突 (conflict)。如果遇到衝突,Git 會停止 rebase,並讓你去解決衝突;在解決完衝突後,可以用"git-add"命令去標記此衝突已經解決。 然後,你無需執行 git commit,只要執行:

$ git rebase --continue

這樣 git 會繼續應用餘下的補丁。

如果你rebase到一半,突然後悔了,你可以用--abort引數來終止 rebase,並且"mywork" 分支會回到 rebase 開始前的狀態。

$ git rebase --abort

----請各位磚家斧正----

【完】

參考資料

【1】https://stackoverflow.com/questions/10058068/in-a-git-cherry-pick-or-rebase-merge-conflict-how-are-base-aka-the-ancestor

【2】http://gitbook.liuhui998.com/4_2.html

【3】https://codeday.me/bug/20180228/136734.html