Git merge | rebase的區別以及使用場景


前言

這么久以來不管是更新當前分支代碼,還是合並代碼,都是使用的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 的基本原則

  1. 下游分支更新上游分支內容的時候根據情況使用master或rebase
  2. 上游分支合並下游分支內容的時候使用 merge
  3. 更新當前分支的內容時一定要使用 --rebase 參數

上游和下游:一直有一個固定上游,就是master分支,所有分支向上追溯的根源都是master,所以上游和下游是相對的,上游就是從當前分支還新拉了一個分支,那當前分支就是上游,下游就是你從其他分支拉的最新分支。

現在有三個分支,master、merge_test、rebase_test分支來對三種場景進行演示

1.下游分支更新上游分支內容的時候根據情況使用master或rebase

  1. master更新文件,push, 提交日志如下圖:

  2. merge_test分支使用merge更新master分支的代碼:因為下游分支一直在提交新的改動代碼,所以想要更新上游分支時,如果使用merge的話,那會多出一行merge的提交記錄。
    雖然沒什么影響,中間插入這么一條記錄,看起來時間線根本不好看。merge_test分支查看git日志如下圖:

  3. 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中在rebasepush會有以下提示,再次點擊rebase即可:

這里又會引發出另一個問題,一個文件的多次提交合並到當前分支都有沖突的話,有多少次提交與當前的分支有沖突,就會解決多少次沖突,而不是以合並前最近修改的結果來解決沖突,所以在一個文件多次修改一處地方后提交了多次代碼日志,建議將多次提交日志壓縮合並(squash)到一條提交記錄中,就可以只解決最近一條提交記錄的沖突即可。


2.上游分支合並下游分支內容的時候使用 merge

這個操作切記不要使用rebase了,因為下游全是基於上游開發的,所以上游使用merge即可。


3.更新當前分支的內容時一定要使用 --rebase 參數

更新當前分支代碼時,會有兩種方式:

當前分支因為可能會有多個小伙伴同事在提交代碼,所以要不定時的更新下當前分支的代碼。以前習慣性的喜歡用mergepull更新代碼,也會發現每次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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM