GIT學習筆記(5):變基rebase
變基
引入變基
在Git中整合來自不同分支的修改主要有兩種方法:merge以及rebase。
整合分支最容易的方法是merge,他會把兩個分支的最新快照以及兩者最近的共同祖先進行三分合並,合並的結果是生成一個新的快照(並提交)。如下圖所示:
其實,還有一種方法,我們可以提取在TESTING在COMMIT:vg65w上所做的修改,然后根據它在MASTER所在的COMMIT:gta24上重新做一遍,就像重新播放一樣,這樣提交到某一分支上的所有修改都已到了另一分支上,我們稱這種操作為變基。
它的原理是這樣的,首先找到這兩個分支(即當前分支TESTING,以及目標基底分支MASTER)的最近共同祖先,然后對比當前分支(TESTING)相對於該祖先的歷次提交,提取相應的修改保存為臨時文件,然后以基底分支(MASTER)的最后一個提交對象(橙黃色)為新的出發點,逐個應用之前准備好的臨時文件,最后會生成一個新的合並提交對象(紅色),從而改寫TESTING的提交歷史,使它成為MASTER的直接下游。
最后回到master,執行一次快速合並。
在Git中我們需要使用rebase命令來完成這樣的操作。
同樣,我們在合並的過程中也遇到了沖突,這時我們需要,找到沖突文件,如上所述Test.java,進行沖突處理.
處理完沖突以后,我們需要將沖突文件添加到暫存區,同時執行git rebase --continue命令執行后續的變基操作,最后回到master,執行一次快速合並操作即可。
說明:可以使用git rebase --abort命令來取消當前的變基操作。
為什么變基
雖然最后整合得到的結果沒有任何區別,但變基能產生一個更為整潔的提交歷史。如果視察一個變基過的分支的歷史記錄,看起來會更清楚:仿佛所有修改都是在一根線上先后進行的,盡管實際上它們原本是同時並行發生的。
一般我們使用變基的目的,是想要得到一個能在遠程分支上干凈應用的補丁——比如某些項目你不是維護者,但是相幫點忙,最好用變基:
先在你自己的一個分支中進行開發,當准備向主項目提交補丁的時候,根據最新的origin/master進行一次變基操作然后再提交,這樣維護者就不需要做任何整合工作(實際上是把解決分支補丁同最新主干代碼之間沖突的責任,化轉為由提交補丁的人來解決),只需要根據你提供的倉庫地址做一次快速合並,或者直接采納你提交的補丁。
請注意,合並結果中最后一次提交所指向的快照,無論是通過變基,還是三方合並,都會得到相同的快照內容,只不過提交歷史不同罷了。變基是按照每行的修改次序重演一遍修改,而合並是把最終結果合在一起。
指定分支進行變基
變基也可以放到其他分支進行,並不一定非得根據分化之前的分支。在對兩個分支進行變基時,所生成的“重放”並不一定要在目標分支上應用,你也可以指定另外的一個分支進行應用。
假設你希望將 client
中的修改合並到主分支並發布,但暫時並不想合並 server
中的修改,因為它們還需要經過更全面的測試。 這時,你就可以使用 git rebase
命令的 --onto
選項,選中在 client
分支里但不在 server
分支里的修改(即 C8
和 C9,沒有C3,是因為C3存在於server分支里
),將它們在 master
分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client
分支,找出處於 client
分支和 server
分支的共同祖先之后的修改,然后把它們在 master
分支上重放一遍”。 這理解起來有一點復雜,不過效果非常酷。
現在可以快進合並 master
分支了
接下來你決定將 server
分支中的修改也整合進來。 使用 git rebase [basebranch] [topicbranch]
命令可以直接將特性分支(即本例中的 server
)變基到目標分支(即 master
)上。這樣做能省去你先切換到 server
分支,再對其執行變基命令的多個步驟。
$ git rebase master server
最后進行快速合並,然后刪除client分支和server分支,形成了一條清晰的提交歷史
變基的風險
在變基的時候,我們要遵循一條准則:
一旦分支中的提交的對象發布到公共倉庫,就千萬不要對該分支進行變基操作。
如果你遵循這條金科玉律,就不會出錯錯,否則要向全國人民謝罪!
在進行變基的時候,實際上拋棄了一些現存的提交對象而創造了一些類似但不同的新的提交對象。如果你把原來分支中的提交對象發布出去,並且其他人更新下載后在其基礎上開展工作,而稍后你又用 git rebase
拋棄這些提交對象,把新的重演后的提交對象發布出去的話,你的合作者就不得不重新合並他們的工作,這樣當你再次從他們那里獲取內容時,提交歷史就會變得一團糟。
參考資料
-
《GIT官方文檔》