Git筆記與思考四:變基

概念

變基(Rebase)也是合代碼的一種手段。
變基與合并(Merge)不同的是,他可以修改歷史,使用rebase來代替merge合代碼的話,得到的歷史記錄是一條直線提交歷史,無分叉,很漂亮。
然而這也是它的缺點,它抹去了分支歷史信息,無法追溯。

指令

變基指令和合并類似,也是對分支進行操作,所以需要指定一個分支名

git rebase 分支名

合并時所指定的分支,是被合進來的分支,意思是把別人的東西納入給自己。
而變基的數(shù)據(jù)流向似是相反,變基指令所指定的分支,是自己將要注入的目的地。
變基指令發(fā)出時,是把自己接在目標分支的后面,所以變基變的是自己。

merge和rebase的數(shù)據(jù)流向

你可能會疑惑,當我要把兩個分支合并時,或者變基時,是要站在分支1的角度合分支2,還是反過來?
為此,來做個實驗,搞清楚它們的方向。這里我起了個名字叫數(shù)據(jù)流向,可能起得不恰當,將就著看,意思懂就行,不用執(zhí)著文字相。

公共祖先

創(chuàng)建一個空倉庫,默認得到一個master分支,任意放個文件,進行一次初始化提交。

git init
touch foo.txt
git add --all
git commit -m "init"

然后再創(chuàng)建一個分支feature

git branch feature
初次提交.png

這時,分支master和分支feature都指向初始提交,這個提交點作為兩條分支的公共祖先。

并行開發(fā)

現(xiàn)在讓master分支和feature分支有其各自的修改提交,且提交時間無序,我們來模擬這個情景。

### 在master分支提交MA
git checkout master
touch MA.txt
git add --all
git commit -m "MA"
### 在feature分支提交FA
git checkout feature
touch FA.txt
git add --all
git commit -m "FA"
### 在master分支提交MB
git checkout master
touch MB.txt
git add --all
git commit -m "MB"
### 在feature分支提交FB
git checkout feature
touch FB.txt
git add --all
git commit -m "FB"
并行開發(fā).png

現(xiàn)在前置工作準備好了,可以把項目復制4份,以便進行幾種合并結果的比較。

四種合代碼方式

接下來,我們嘗試四種合代碼方式,分別是:

  • merge master
  • merge feature
  • rebase master
  • rebase feature

對復制的4份項目,分別執(zhí)行指令,得到如下結果:

merge master.png

git merge master:在feature分支上發(fā)出合并指令,這樣會把master分支的提交合到feature自己身上,然后再創(chuàng)建一次合并提交。

merge feature.png

git merge feature:在master分支上發(fā)出合并指令,這樣會把feature分支的提交合到master自己身上,然后再創(chuàng)建一次合并提交。

rebase feature.png

git rebase feature:在master分支上發(fā)出變基指令,這樣會把master分支異于feature分支的提交接在feature之后。

rebase master.png

git rebase master:在feature分支上發(fā)出變基指令,這樣會把feature分支異于master分支的提交接在master之后。

比較幾種合代碼的情況,如果要進行merge操作的話,最好是在主分支上執(zhí)行merge,把次分支的代碼合進來;如果要進行rebase操作的話,最好是在次分支上進行,把自己變基合入主分支。

變基的工作原理

變基其實是復制要被變基的分支上的提交,然后在別的分支上把提交依次重演出來。
注意這是復制,而不是移動。也就是說,舊有分支的提交還是可以通過hash值找回來的,在沒被gc清理的前提下。

由于變基的原理是復制,這導致產(chǎn)生新的提交。在上一小節(jié)的實驗中,比如rebase master操作,從現(xiàn)實時間上來說,MB提交是遲于FA提交中,但變基結果是FAMB之后,為什么?
因為變基后的FA已經(jīng)不是原feature分支上的FA了,它是在變基過程中新產(chǎn)生的一個復制結果,其提交信息也已經(jīng)被改變。
再者,變基完成后,從版本庫歷史上,也已經(jīng)看不出哪些提交是屬于哪個分支的了。
可以說,變基修改了歷史。

變基的沖突

在合并時會遇到的沖突情況,在變基時也一樣不能避免。
由于變基過程,是一個一個新復制的提交在另一條分支上重演出來,所以可能會出現(xiàn)多次沖突的情況。
在提交重演的時候,每遇到一次沖突,變基過程就會暫停下來,這時,你需要手動處理沖突的文件,處理完后add到暫存區(qū),然后使用如下指令讓變基繼續(xù)。

git rebase --continue

當然,如果你有很多個提交在重演時都沖突的話,意味著你需要多做幾次continue...

移植分支

普通變基的指令是這樣的: git rebase master
移植分支的指令是這樣的:git rebase master --onto 另一分支名
怎么理解?
如果不加--onto選項,其實是把自己移植到了目標分支master上,如果加了--onto 分支名,就會把原本要接到目標master的提交,拐了個彎,接到了指定的另一個分支那里去。
就這么回事^ ^。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容