git里面的rebase總是讓人覺得很難理解
特別是它的中文翻譯:變基
圖片來自廖雪峰
首先不認識rebase,先查查詞典好吧意思是:重定基准
所以這個翻譯還是非常准確的。
如果還是覺得不好理解,注意,前方高能。
按照下面的步驟,我們換一個容易理解的詞:
- java里面的基類我們也可以說是父類所以 (基==父)
- 變換變換 。變字和換字應該差不多。 我們就認為 (變==換)
- 等價代換一下 (變基==換父)
- 換父? 不就是: 換爹 !!!!!!
好了經過上面的步驟,我們成功的將
我們的標題從git rebase 什么是變基 變為 git rebase 什么是換爹。
我們知道git中的commit也是有父子關系的。
所以到這里相信你已經明白了:變基變基,就是某個commit-B不想要commit-A這個爹了。要換個別的commit-C做自己的爹。
說到這里換爹都知道是干啥的,那么我們為什么要換爹呢?什么時候要用到換爹呢?
下面介紹一下需要換爹的場景:
合並多個commit
- 一個分支上依次有A - F ,一共6個commit。這個分支 每一個commit 都是獨苗,也很頑強的這么多代都沒有斷了香火。從commit_B到commit_E這么多代人就干了一件事兒就是蓋了個房子。史書上(log)覺得不用分成這么多commit,想要合並一下。合並連續commit
- commit_A在房子的門口種了一棵樹,到了commit_F的時候又在門口種了棵樹。史書覺得都是種樹,干脆把commit_A和commit_F合並了吧。合並非連續的commit
修改commit message(很久之前的commit message)
這個過程沒有換爹,使用rebase 命令的目的是可以通過這個操作修改commit message
合並分支
我們想要把topic分支合並到master。
在topic分支 執行這兩個命令任意一個
git rebase master
git rebase master topic
可以達到下圖的效果。
這里我們發現,topic從master分支分出去之后的所有commit:A、B、C,作用在了master的最后一個commit G之后。
每當rebase操作分支的時候 總是有些難以理解。這里我們說其實rebase命令本質上一直都是換爹。
分支名我們可以認為是執行相應分支最新commit的指針
分支名topic代表的是topic從master分出去之后的所有的commit
而分支名master代表的master分支上最新的commit。
為了驗證以上的說法,可以執行以下命令
git rebase commit_F_id topic
執行后得到以下分支圖
注意,以下驗證屬於比較危險的行為,如果不熟悉。建議不要在重要的項目中嘗試
我們可以再驗證一次,執行
git rebase commit_G_id commit_C_id
執行后得到以下分支圖
我們注意到該命令與 git rebase master topic 相似。但是注意此時master 和 topic分支的指針的位置。commit G后面的幾個commit是不在任何分支上的。屬於比較危險的行為。
我們可以再驗證一次,執行
git rebase commit_G_id commit_A_id
執行后得到以下分支圖
也是比較危險的行為。
總結一下
rebase是一個強大的命令。在以上常見的場景中的確是很方便。
其本質就是給某個commit 換一個父 commit
不建議在復雜的場景中使用!rebase有風險。
還有一條必須遵守:rebase 不能用來操作與他人協作的分支
比如topic是你自己的分支,git rebase master topic 沒有問題,但是git rebase topic master就會給你的同事帶來麻煩。