前言
這么久以來不管是更新當前分支代碼,還是合並代碼,都是使用的merge,但也知道有rebase的操作,就是不理解其究竟有什么區別,且merge用了這么久沒出過啥問題,就沒深究過rebase。現在抽空出來,研究一下,實際rebase的使用場景還是挺多,而且這些場景下使用rebase的姿勢也要比merge正確。
merge與rebase的區別
rebase會把你當前分支的 commit
放到公共分支的最后面,所以叫變基。就好像你從公共分支又重新拉出來這個分支一樣。
舉例:如果你從 master
拉了個feature
分支出來,然后你提交了幾個 commit
,這個時候剛好有人把他開發的東西合並到 master
了,這個時候 master
就比你拉分支的時候多了幾個 commit
,如果這個時候你 rebase master
的話,就會把你當前的幾個 commit
,放到那個人 commit
的后面。
merge 會把公共分支和你當前的 commit
合並在一起,形成一個新的 commit
提交
使用 rebase 和 merge 的基本原則
- 下游分支更新上游分支內容的時候根據情況使用master或rebase
- 上游分支合並下游分支內容的時候使用 merge
- 更新當前分支的內容時一定要使用 --rebase 參數
上游和下游:一直有一個固定上游,就是master分支,所有分支向上追溯的根源都是master,所以上游和下游是相對的,上游就是從當前分支還新拉了一個分支,那當前分支就是上游,下游就是你從其他分支拉的最新分支。
現在有三個分支,master、merge_test、rebase_test分支來對三種場景進行演示
1.下游分支更新上游分支內容的時候根據情況使用master或rebase
-
master更新文件,push, 提交日志如下圖:
-
merge_test
分支使用merge
更新master
分支的代碼:因為下游分支一直在提交新的改動代碼,所以想要更新上游分支時,如果使用merge的話,那會多出一行merge
的提交記錄。
雖然沒什么影響,中間插入這么一條記錄,看起來時間線根本不好看。merge_test分支查看git日志如下圖:
-
rebase_test
分支使用rebase
更新master
分支的代碼:此時如果我們使用rebase
來更新master
的代碼到開發分支,就是所謂的“變基”,將master的提交記錄,全部遷移到當前開發分支,當前分支就是以master
為基礎重新更新的分支。就像是當時從master
拉出來時一樣,在開發分支會有創建分支之前,在上游分支的git提交記錄。rebase_test
分支查看git日志如下圖,就不會存在上面merge
操作更新后,多的那一行記錄。
使用rebase
之后,如果直接使用git push origin rebase_test
發現是不好使的,會有問題提示說明,相對遠程rebase_test
分支而言,本地倉庫的rebase_test
分支的“基底”已經變化了,直接push
是不行的,所以確保沒有問題的情況下必須使用--force
參數才能提交,這也就是官方對rebase
作為 “變基” 的解釋(個人觀點)
idea中在rebase
后push
會有以下提示,再次點擊rebase
即可:
這里又會引發出另一個問題,一個文件的多次提交合並到當前分支都有沖突的話,有多少次提交與當前的分支有沖突,就會解決多少次沖突,而不是以合並前最近修改的結果來解決沖突,所以在一個文件多次修改一處地方后提交了多次代碼日志,建議將多次提交日志壓縮合並(squash
)到一條提交記錄中,就可以只解決最近一條提交記錄的沖突即可。
2.上游分支合並下游分支內容的時候使用 merge
這個操作切記不要使用rebase
了,因為下游全是基於上游開發的,所以上游使用merge
即可。
3.更新當前分支的內容時一定要使用 --rebase
參數
更新當前分支代碼時,會有兩種方式:
當前分支因為可能會有多個小伙伴同事在提交代碼,所以要不定時的更新下當前分支的代碼。以前習慣性的喜歡用merge
來pull
更新代碼,也會發現每次pull
后,會多出一行提交記錄:
Merge remote-tracking branch 'origin/merge_test' into merge_test
因為插入了上面這條提交記錄,這樣看起來整個分支的提交記錄就被打亂了,整個提交記錄也就不連貫了,所以建議使用rebase
來進行更新當前分支的代碼。
使用 rebase
就感覺所有人都在同一條直線上開發一樣,歷史提交線會很清晰。
還有一個原因:Rebase the currenct branch on top of the incoming changes,把當前分支的基放在即將拉下來的change 的上面。它相當於后移了自己本地分支的檢出commit~
以上是結合多個博客總結的,參考原文鏈接:
https://zhuanlan.zhihu.com/p/34197548
https://www.jianshu.com/p/4079284dd970