【git命令】git-rebase

修改歷史提交記錄

做用簡要歸納爲:能夠對某一段線性提交歷史進行編輯、刪除、複製、粘貼;所以,合理使用rebase命令可使咱們的提交歷史乾淨、簡潔!git

 前提:不要經過rebase對任何已經提交到公共倉庫中的commit進行修。shell

1.合併多個commit爲一個完整commit

咱們在本地倉庫中提交了屢次,在咱們把本地提交push到公共倉庫中以前,爲了讓提交記錄更簡潔明瞭,咱們但願把以下分支B、C、D三個提交記錄合併爲一個完整的提交,而後再push到公共倉庫。app

如今咱們在測試分支上添加了四次提交,咱們的目標是把最後三個提交合併爲一個提交:測試

這裏咱們使用命令:3d

git rebase -i  [startpoint]  [endpoint]

區間指定的是一個前開後閉的區間日誌

其中-i的意思是--interactive,即彈出交互式的界面讓用戶編輯完成合並操做,[startpoint] [endpoint]則指定了一個編輯區間,若是不指定[endpoint],則該區間的終點默認是當前分支HEAD所指向的commit(注:該區間指定的是一個前開後閉的區間)。 在查看到了log日誌後,咱們運行如下命令:code

git rebase -i 53d6d02df

blog

git rebase -i HEAD~3

而後咱們會看到以下界面:索引

上面未被註釋的部分列出的是咱們本次rebase操做包含的全部提交,下面註釋部分是git爲咱們提供的命令說明。每個commit id 前面的pick表示指令類型,git 爲咱們提供瞭如下幾個命令:ip

pick:保留該commit(縮寫:p)
reword:保留該commit,但我須要修改該commit的註釋(縮寫:r)
edit:保留該commit, 但我要停下來修改該提交(不只僅修改註釋)(縮寫:e)
squash:將該commit和前一個commit合併(縮寫:s)
fixup:將該commit和前一個commit合併,但我不要保留該提交的註釋信息(縮寫:f)
exec:執行shell命令(縮寫:x)
drop:我要丟棄該commit(縮寫:d)

根據咱們的需求,咱們將commit內容編輯以下:

而後是註釋修改界面:

編輯完保存便可完成commit的合併了:

#2. 將某一段commit粘貼到另外一個分支上

當咱們項目中存在多個分支,有時候咱們須要將某一個分支中的一段提交同時應用到其餘分支中,就像下圖:

咱們但願將develop分支中的C~E部分複製到master分支中,這時咱們就能夠經過rebase命令來實現(若是隻是複製某一兩個提交到其餘分支,建議使用更簡單的命令:git cherry-pick)。

在實際模擬中,咱們建立了master和develop兩個分支:

master分支:

develop分支:

咱們使用命令的形式爲:

git rebase   [startpoint]   [endpoint]  --onto  [branchName]

其中,[startpoint] [endpoint]仍然和上一個命令同樣指定了一個編輯區間(前開後閉),--onto的意思是要將該指定的提交複製到哪一個分支上。

因此,在找到C(90bc0045b)和E(5de0da9f2)的提交id後,咱們運行如下命令:

git  rebase   90bc0045b^   5de0da9f2   --onto master

能夠看到,C~E部分的提交內容已經複製到了G的後面了,大功告成?NO!咱們看一下當前分支的狀態:

當前HEAD處於遊離狀態,實際上,此時全部分支的狀態應該是這樣:

因此,雖然此時HEAD所指向的內容正是咱們所須要的,可是master分支是沒有任何變化的,git只是將C~E部分的提交內容複製一份粘貼到了master所指向的提交後面,咱們須要作的就是將master所指向的提交id設置爲當前HEAD所指向的提交id就能夠了,即:

git checkout master
git reset --hard  0c72e64

此時咱們才大功告成!

3. rebas合併,解決衝突

分支合併

若是圖中此時network 和 origin 分支有衝突了

平時咱們用merge, merge合併,手動解決衝突,merge後會產生一個新的commit-id

分支合併,解決衝突, merge後會產生一個新的commit-id

rebase 合併

命令:

git checkout mywork

git rebase origin

命令會把你的"mywork"分支裏的每一個提交(commit)取消掉,而且把它們臨時 保存爲補丁(patch)(這些補丁放到".git/rebase"目錄中),而後把"mywork"分支更新 爲最新的"origin"分支,最後把保存的這些補丁應用到"mywork"分支上。

當'mywork'分支更新以後,它會指向這些新建立的提交(commit),而那些老的提交會被丟棄。 若是運行垃圾收集命令(pruning garbage collection), 這些被丟棄的提交就會刪除. (請查看 git gc)

在rebase的過程當中,也許會出現衝突(conflict). 在這種狀況,Git會中止rebase並會讓你去解決 衝突;在解決完衝突後,用"git-add"命令去更新這些內容的索引(index), 而後,你無需執行 git-commit,只要執行:

git rebase --continue

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

在任什麼時候候,你能夠用--abort參數來終止rebase的行動,而且"mywork" 分支會回到rebase開始前的狀態。

git rebase --abort

若是你想跳過此補丁,則執行 git rebase --skip

相關文章
相關標籤/搜索