大家好,我是七哥,好久不见了。前一阵回老家后事情比较多,包括找工作、新入职的适应等等,还是比较累。
最近也算是告一段落了,新入职的公司感觉也蛮不错的,后面时间多了会多输出一些技术文章和视频,大家期待一波哈😄。
最近新入职,在提交pr,然后 code review 后,关于分支合并我产生了一个小问题,那就是 squash merge
和 rebase merge
到底有什么区别呢?公司为什么要求使用 git rebase merge
呢?之前我们都是直接一把梭 git merge 分支名
来合并。
带着这两个疑问我们以一个实际的开发场景来搞明白 merge
, squash merge
, 和 rebase merge
之间的区别,接着往后看吧。
举个例子,如果我们有一个项目,它包含一个 master
主分支,有3个提交,分别是1、2、3和1个功能开发分支 dev
,在功能分支上提交A、B 、C如下图所示。
现在我们完成了dev分支的开发测试工作,需要把dev分支合并回master分支。
这是最基本的merge,就是把提交历史原封不动的拷贝过来,包含完整的提交历史记录。
$ git checkout master
$ git merge dev
此时还会生产一个 merge commit (D')
,这个 merge commit
不包含任何代码改动,而包含在dev分支上的几个commit列表(A, B和C)。查看git的提交历史(git log)可以看到所有的这些提交历史记录。
根据字面意思,这个操作完成的是压缩的提交,解决的是什么问题呢?由于在dev分支上执行的是开发工作,有一些很小的提交,或者是纠正前面的错误的提交,对于这类提交对整个工程来说不需要单独显示出来一次提交,不然导致项目的提交历史过于复杂。所以基于这种原因,我们可以把dev上的所有提交都合并成一个提交;然后提交到主干。
在这个例子中,我们把A,B和C的改动合并成了一个D。
注意,squash merge 并不会替我们产生提交D,它只是把所有原本属于A、B和C的改动合并,然后放在本地文件,需要你再次手动执行 git commit
操作。
此时又要注意了,因为你要你手动 commit,也就是说这个 commit 是你产生的,不是由原来 dev 分支上的开发人员产生的,提交者本身发生了变化。也可以这么理解,就是你把 dev 分支上的所有代码改动一次性提交到 master 分支上而已。
由于 squash merge
会变更提交者作者信息,这是一个很大的问题,后期问题追溯不好处理(当然也可以由分支dev的所有者来执行 squash merge
操作,以解决部分问题),rebase merge
可以保留提交的作者信息,同时可以合并commit历史,完美的解决了上面的问题。
$ git checkout dev
$ git rebase -i master
$ git checkout master
$ git merge dev
rebase merge
分两步完成:
第一步:执行rebase操作,结果是看起来dev分支是从主分支的提交3拉出来的,而不是从提交2拉出来的,然后使用-i参数手动调整commit历史,是否合并如何合并。例如 rebase -i
命令会弹出文本编辑框:
pick <A> Message for commit #1
pick <B> Message for commit #2
pick <C> Message for commit #3
假设提交B是对提交A的一个拼写错误修正,因此可以不需要显式的指出来,我们把B修改为fixup:
pick <A> Message for commit #1
fixup <B> Message for commit #2
pick <C> Message for commit #3
rebase之后的状态变为:
A' 是A和B的合并。
第二步:再执行merge操作,把dev分支合并到master分支:
注意:
在执行 rebase
的时候可能会出现冲突的问题,此时需要手工解决冲突的问题,然后执行(git add)命令;
所有冲突解决完之后,这时不需要执行(git commit)命令,而是运行(git rebase --continue)命令,一直到rebase完成;如果中途想放弃rebase操作,可以运行(git rebase --abort)命令回到rebase之前的状态。
因为 rebase 会修改历史记录,将当前分支的提交记录先取消,更新远程分支的记录进来作为基础版本,然后在应用当前分支的提交记录,所以如果当前分支别人也在使用,还是需要小心,因为改变了历史记录有可能会对别人产生影响,但是如果是你自己的分支就可以合并以及隐藏你的具体提交记录和创建的分支。
因此如果 branch 是私有分支,rebase 可以有效帮你「重整版本」来保持 commit 记录是呈线性整齐,我们公司目前是一个任务拉一个分支,在合并之前可以使用 git rebase master 将主干分支其他人的提交记录做为基础版本然后应用你个人分支的变更,这样可以保持提交记录的有序性,然后在 pr 通过后使用 squahs merge
来合并分支。
因为有可能你个人分支上做了很多次 commit,这个对于主干分支来说是不需要关注的,其他人只需要关注你这某一个需求做完了合并进来即可,所以合并为一次是比较合理的,可以避免太多的提交记录造成困扰。
到这里 git 合并分支的三种方式你应该都理解了,如果还有啥疑问欢迎一起交流学习。也欢迎给文末点个赞哦👍。
作者介绍: 七哥,非科班转行程序员,靠努力学习一步步成功,写文章也经常拍视频,专注编程技术与个人成长干货分享,愿望是陪家人平淡快乐的度过一生!
留个个人微信二维码
欢迎做个点赞之交