git merge时merge/squash merge/rebase merge的区别

git merge时merge/squash merge/rebase merge的区别

1. merge

$ git checkout master
$ git merge dev

这是最基本的 merge,会把分支的提交历史原封不动地拷贝过来,如果 master 此后已经有了新的提交,那么本次 merge 时还会额外自动创建一条 commit 信息用于记录本次 merge 操作。

2. squash merge

$ git checkout master
$ git merge --squash dev

字面意思,相比 merge 来说会减少分支合并的记录,会被压缩为一条 commit 记录。squash merge 本质是把 dev 分支的改动保存到 master 本地,接下来还需要手动提交一下,因此最终提交者变成了操作 master 分支的人,这可能是个弊端。

3. rebase merge

$ git checkout dev
$ git rebase -i master
$ git checkout master
$ git merge dev

rebase merge 可以完美解决 squash merge 可能会变更原始提交者的问题。

首先 rebase 这个概念如果不懂可以先去了解下,这里先进行 rebase 的意义,个人认为,一方面是为了和 master 分支同步一下信息,以免 master 在和 dev 分叉之后又有了额外的更新;另一方面,能真正解决 squash merge 痛点的是 -i 交互模式,会进入文本编辑框,由自己指定 dev 相对于 master 新产生的这些“补丁” 在 rebase 时具体该如何应用到当前 dev 分支上。

所以 rebase merge 是非常灵活的,你可以什么都不干,采用默认策略:

pick xxxxxxx A
pick xxxxxxx B
pick xxxxxxx C

也可以把所有 commit 合为一条,保存退出后,会再次进入一个用于编辑合并后提交信息的文本编辑框:

pick xxxxxxx A
squash xxxxxxx B
squash xxxxxxx C

还可以不合为一条,而只合并其中某几条,比如把 A,B,C 三条提交记录整合为 AB,C 两条记录:

pick xxxxxxx A
fixup xxxxxxx B
pick xxxxxxx C

文本编辑框中定义的指令合理的话,应该会顺利 rebase 成功,之后可以 git log 查看一下是否如愿。
最后,在 master 分支上进行 git merge dev 就是常规操作了。

所以 squash merge 和 rebase merge 在多条合并为一条时的区别是,前者在 merge 时才合并为一条,而后者在提前 rebase 时就顺便整合了多条 commit 信息。


参考:

  1. git merge的三种操作merge, squash merge, 和rebase merge