Git merge rebase 对比
Git merge rebase 对比
在平时的开发过程中,分支之间的合并是十分常见的操作。我平时都是使用 merge 一把嗦,无论是开发分支到线上分支,还是线上分支到开发分支,基本都是使用的 merge。反观之前有一个后端同事,他们组内会有多人开发同一个功能的情况,他除了最终将开发分支合并到线上分支使用了 gitlab 的 merge request 去 merge,平时都是使用 rebase 来将别人的功能分支合并到自己的开发分支上。
在看到了这些情况后,我对 merge 和 rebase 有什么区别产生了疑问,正好去搞明白这两个操作究竟有什么不同。
merge 是我常用的功能,这个我自己比较熟悉,一般来说可以分成两种情况:当前分支与合并目标分支有无变更。如果当前分支就是从合并目标分支上出来的,merge 操作其实看起来就像是在合并目标分支后进行了多次 commit,commit log 也是一条直线;但很多情况下存在多人同时开发的情况,就会有变更操作,存在变更操作的时候,merge 操作会产生一条 merge 的 commit log,commit log 也会变成一条折线。很多同学可能会有强迫症介意这条折线,所以 rebase 是他们更常见的选择。
接下来我们聊一下 rebase,上面说到 rebase 和 merge 最直观的区别就是 rebase 合并完成后 commit log 是一条直线,那么我们就会去想为什么它能变成一条直线呢?在了解了 rebase 的原理之后发现其实很简单,以之前我用过的 cherry-pick 功能为例,cherry-pick 其实就是选定一些 commit,重新在当前分支上进行提交,rebase 亦是同理,本质上其实就是分析了两条分支的相同点与差异点,然后依次重新应用提交,生成新的 commit 记录。既然都是在当前分支上进行新的提交,那自然就是一条直线了。rebase 会带来的问题就是,commit id 记录都不一样了,对于 github 等环境推送时会出现推送失败的情况。
在理解了两者的原理之后,大概对 merge 和 rebase 就有了一个清晰的认知了。两个操作本质上都是进行分支合并,只是两者的操作方式不一样,下面是一个对比的表格:
特性 | Git Merge | Git Rebase |
---|---|---|
历史记录 | 保留所有分支和合并的历史记录 | 创建线性的提交历史 |
提交记录 | 生成一个新的合并提交 | 重新应用提交,生成新的提交对象 |
冲突解决 | 在合并时统一解决冲突 | 在每个提交时逐一解决冲突 |
操作复杂度 | 操作简单,适合大多数场景 | 需要理解其工作原理,避免在公共分支使用 |
适用场景 | 适用于公共分支和团队协作 | 适用于个人分支的整洁提交 |
在对比了两者的区别后,我认为一个较好的流程是:
个人分支同步到正式分支时,用 merge,目的是保留提交记录与合并记录,方便后期溯源找到是哪个版本引入的问题。
而在功能分支合并到个人分支的时候,可以使用 rebase,将提交记录线性化,整理和优化提交历史。
但最终使用何种方式,还是需要看项目组成员的使用习惯与规范,我们能做的就是搞清楚每一种操作的区别,并在不同需求时使用最优的方案去解决。