說明
本篇文章是爲了理解git rebase
命令而寫,也是對Pro Git 3.6 Git 分支 - 變基 章節的總結。
什麼是變基?
使用rebase命令將提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一樣(將一個分支的修改操作在另一個分支最新的提交基礎上在依次應用)。
變基的目的?
一般我們這樣做的目的是爲了確保在向遠程分支推送時能保持提交歷史的整潔——例如向某個其他人維護的項目貢獻代碼時。 在這種情況下,你首先在自己的分支裏進行開發,當開發完成時你需要先將你的代碼變基到 origin/master 上,然後再向主項目提交修改。 這樣的話,該項目的維護者就不再需要進行整合工作,只需要快進合併便可。
怎樣使用變基?
git rebase branch-name。例如在iss33分支執行git rebase master表示將iss33分支的commit對象在master分支重放一次(依次應用)。
變基原理?
通過一個事例來說明變基的原理。假設我們有一個master分支,master分支已經有了三次提交(7c3eefb、f9318aa、f9318aa)。撿出iss33分支,分別在master和iss33分支進行修改a.txt文件並提交到對應的分支本地倉庫中(如圖:在master分支上撿出iss33分支,並在兩個分支各做一次commit)。
撿出iis33分支(git checkout iss33),執行 git rebase master,這時Git會找到master和iss33最近一個共同的父commit對象,並找出這個共同的父commit對象到iss33分支最新提交對象之間的所有對象,將這些對象在master分支最新一次提交依次應用。這個過程很像將一個數組追加到另一個數組。這時我們git rebase master會提示有衝突(因爲我們在master和iss33都修改了a.txt,並且是同一行代碼),對沖突文件進行手工合共,然後git add .標記衝突解決,git rebase --continue告訴Git衝突已經解決。整個rebase過程完成後提交歷史如圖:在iss33分支上變基(git rebase master)。通過提交歷史可以看到這時我們回到msater分支執行 git merge iss3就可以進行"快進(fast-forward)"模式合併。
注意:git rebase master之後iss33最新的提交從97df2346變成了023c0fb,說明rebase重新生成了一個新commit對象替換原來的commit對象。變基操作的實質是丟棄一些現有的提交,然後相應地新建一些內容一樣但實際上不同的提交。
變基過程中常用的幾個命令
例如我們需要將iss33變基到master分支上,使用命令git checkout iss33;git rebase master
,此時會進入rebase模式,如果iss33和master分支中的提交有衝突,需要手動合併文件解決,解決衝突後使用git add
表示衝突已經解決,git rebase --continue
表示繼續下一個衝突,git rebase --skip
表示跳過當前衝突,git rebase --abort
表示退出rebase模式,回到運行git rebase master
命令之前的狀態。
什麼情況下應該避免使用變基?
不應該對已經推送到遠程倉庫的提交歷史進行rebase操作——————切記。
比如我們將合併後的dev和master分支提交歷史推送到了遠程倉庫。
(合併歷史記錄)
C3->C4-dev
/
/
C1->C2->C5-master
提交裏推送到了遠程倉庫,然後發現記錄不夠簡潔,我們在本地進行rebase,然後再git push --force覆蓋遠程倉庫上的推送。–不要這樣使用rebase,切記。
(rebase歷史記錄)
C1->C2->C5->CC3’->CC4’-master-dev