3.6 變基

2018-02-24 15:22 更新

變基

在 Git 中整合來自不同分支的修改主要有兩種方法:merge 以及 rebase。在本節(jié)中我們將學習什么是“變基”,怎樣使用“變基”,并將展示該操作的驚艷之處,以及指出在何種情況下你應避免使用它。

變基的基本操作

請回顧之前在 “分支的合并” 中的一個例子,你會看到開發(fā)任務分叉到兩個不同分支,又各自提交了更新。

Figure 3-28. 通過合并操作來整合分叉了的歷史

其實,還有一種方法:你可以提取在 C4 中引入的補丁和修改,然后在 C3 的基礎上再應用一次。在 Git 中,這種操作就叫做 變基。你可以使用 rebase 命令將提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一樣。

在上面這個例子中,運行:

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

它的原理是首先找到這兩個分支(即當前分支 experiment、變基操作的目標基底分支 master)的最近共同祖先 C2,然后對比當前分支相對于該祖先的歷次提交,提取相應的修改并存為臨時文件,然后將當前分支指向目標基底 C3, 最后以此將之前另存為臨時文件的修改依序應用。(譯注:寫明了 commit id,以便理解,下同)

Figure 3-30. master 分支的快進合并

此時,C4' 指向的快照就和上面使用 merge 命令的例子中 C5 指向的快照一模一樣了。這兩種整合方法的最終結(jié)果沒有任何區(qū)別,但是變基使得提交歷史更加整潔。你在查看一個經(jīng)過變基的分支的歷史記錄時會發(fā)現(xiàn),盡管實際的開發(fā)工作是并行的,但它們看上去就像是先后串行的一樣,提交歷史是一條直線沒有分叉。

一般我們這樣做的目的是為了確保在向遠程分支推送時能保持提交歷史的整潔——例如向某個別人維護的項目貢獻代碼時。在這種情況下,你首先在自己的分支里進行開發(fā),當開發(fā)完成時你需要先將你的代碼變基到 origin/master 上,然后再向主項目提交修改。這樣的話,該項目的維護者就不再需要進行整合工作,只需要快進合并便可。

請注意,無論是通過變基,還是通過三方合并,整合的最終結(jié)果所指向的快照始終是一樣的,只不過提交歷史不同罷了。變基是將一系列提交按照原有次序依次應用到另一分支上,而合并是把最終結(jié)果合在一起。

更有趣的變基例子

在對兩個分支進行變基時,所生成的“重演”并不一定要在目標分支上應用,你也可以指定另外的一個分支進行應用。就像 Figure?3-31 中的例子這樣。你創(chuàng)建了一個特性分支 server,為服務端添加了一些功能,提交了 C3C4。然后從 C3 上創(chuàng)建了特性分支 client,為客戶端添加了一些功能,提交了 C8C9。最后,你回到 server 分支,又提交了 C10。

Figure 3-32. 截取特性分支上的另一個特性分支,然后變基到其他分支

現(xiàn)在可以快進合并 master 分支了。(如圖 Figure?3-33):

$ git checkout master
$ git merge client

Figure?3-35 中的樣子:

$ git branch -d client
$ git branch -d server

Figure 3-36. 克隆一個倉庫,然后在它的基礎上進行了一些開發(fā)

然后,某人又向中央服務器提交了一些修改,其中還包括一次合并。你抓取了這些在遠程分支上的修改,并將其合并到你本地的開發(fā)分支,然后你的提交歷史就會變成這樣:

Figure 3-38. 有人推送了經(jīng)過變基的提交,并丟棄了你的本地開發(fā)所基于的一些提交

結(jié)果就是你們兩人的處境都十分尷尬。如果你執(zhí)行 git pull 命令,你將合并來自兩條提交歷史的內(nèi)容,生成一個新的合并提交,最終倉庫會如圖所示:

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號