本篇文章給大家?guī)砹岁P(guān)于git的相關(guān)知識,其中主要介紹了rebase的相關(guān)問題,rebase,變基,可以直接理解為改變基底。feature分支是基于master分支的b拉出來的分支,feature的基底是b,希望對大家有幫助。
推薦學(xué)習(xí):《git》
本文用最簡潔的例子讓你快速掌握rebase原理和用法
一、提交節(jié)點(diǎn)圖解
首先通過簡單的提交節(jié)點(diǎn)圖解感受一下rebase在干什么
兩個分支master和feature,其中feature是在提交點(diǎn)B處從master上拉出的分支
master上有一個新提交M,feature上有兩個新提交C和D
此時切換到feature分支上,執(zhí)行如下命令,相當(dāng)于是想要把master分支合并到feature分支(這一步的場景就可以類比為我們在自己的分支feature上開發(fā)了一段時間了,準(zhǔn)備從主干master上拉一下最新改動)
git checkout featuregit rebase master //這兩條命令等價于git rebase master feature
下圖為變基后的提交節(jié)點(diǎn)圖,解釋一下其工作原理:
- feature:待變基分支、當(dāng)前分支
- master:基分支、目標(biāo)分支
官方解釋(如果覺得看不懂可以直接看下一段):當(dāng)執(zhí)行rebase操作時,git會從兩個分支的共同祖先開始提取待變基分支上的修改,然后將待變基分支指向基分支的最新提交,最后將剛才提取的修改應(yīng)用到基分支的最新提交的后面。
結(jié)合例子解釋:當(dāng)在feature分支上執(zhí)行g(shù)it rebase master時,git會從master和featuer的共同祖先B開始提取feature分支上的修改,也就是C和D兩個提交,先提取到。然后將feature分支指向master分支的最新提交上,也就是M。最后把提取的C和D接到M后面,但這個過程是刪除原來的C和D,生成新的C’和D’,他們的提交內(nèi)容一樣,但commit id不同。feature自然最后也是指向D’。
通俗解釋(重要!!):rebase,變基,可以直接理解為改變基底。feature分支是基于master分支的B拉出來的分支,feature的基底是B。而master在B之后有新的提交,就相當(dāng)于此時要用master上新的提交來作為feature分支的新基底。實際操作為把B之后feature的提交存下來,然后刪掉原來這些提交,再找到master的最新提交位置,把存下來的提交再接上去(新節(jié)點(diǎn)新commit id),如此feature分支的基底就相當(dāng)于變成了M而不是原來的B了。(注意,如果master上在B以后沒有新提交,那么就還是用原來的B作為基,rebase操作相當(dāng)于無效,此時和git merge就基本沒區(qū)別了,差異只在于git merge會多一條記錄Merge操作的提交記錄)
上面的例子可抽象為如下實際工作場景:張三從B拉了代碼進(jìn)行開發(fā),目前提交了兩次,開發(fā)到D了;李四也從B拉出來開發(fā)了并且開發(fā)完畢,他提交到了M,然后合到主干上了。此時張三想拉下最新代碼,于是他在feature分支上執(zhí)行了git rebase master,即把master分支給rebase過來,由于李四更早開發(fā)完并合了主干,如此就相當(dāng)于張三是基于李四的最新提交M進(jìn)行的開發(fā)了。
二、實際git提交示例
按照上面的圖解構(gòu)造了提交記錄,如下圖所示:(ABM是master分支線,ABCD是feature分支線。這里畫成了master變色分叉出來,這不影響理解,知道是表示兩個分支兩條線即可!)
此時,在feature分支上執(zhí)行g(shù)it rebase master
變基完成以后,ABCD是原來的feature分支線,ABMC’D’是新的feature分支線,ABM是master分支線(沒有變化)
三、推薦使用場景
搞來搞去那么多,這其實是最重要的。不同公司,不同情況有不同使用場景,不過大部分情況推薦如下:
- 拉公共分支最新代碼的時候使用rebase,也就是git pull -r或git pull –rebase,但有個缺點(diǎn)就是rebase以后我就不知道我的當(dāng)前分支最早是從哪個分支拉出來的了,因為基底變了嘛。(正因如此,大部分公司其實都不會用rebase,基本統(tǒng)一使用merge,雖然會多出無意義的一條提交記錄“Merge … to …”,但至少能知道誰干了什么事)
- 往公共分支上合代碼的時候,使用merge。(如果使用rebase,那么其他開發(fā)人員想看主分支的歷史,就不是原來的歷史了,歷史已經(jīng)被你篡改了。比如張三和李四從共同的節(jié)點(diǎn)拉出來開發(fā),張三先開發(fā)完提交了兩次然后merge上去了,李四后來開發(fā)完rebase上去(注意李四需要切換到主分支,然后執(zhí)行g(shù)it rebase,然后再git pull到遠(yuǎn)端),則李四的新提交變成了張三的新提交的新基底,本來李四的提交是最新的,結(jié)果最新的提交顯示反而是張三的,就亂套了)
推薦學(xué)習(xí):《git》