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

posted @ 2021-02-23 12:06  惊叫唤  阅读(3527)  评论(0编辑  收藏  举报