Git 三种合并方式(rebase / merge / squash)
问题背景
在使用 Git (分布式版本控制系统),往往不会直接在主分支上面直接开发,而是新建一个分支进行开发。
那么当我们在新分支上面完成一个功能时,便需要合并到主分支。
三种合并
- merge
- rebase and merge
- squash and merge
初始化
图 1
图1,初始两个分支的状态,现基于此对合并(merge)和变基(rebase)操作讲解。
存在两个分支,当前状态为:
- master : A -> B -> C -> D -> E
- feature : A -> B -> C -> F -> H
merge
图 2
图 2 ,当 master 分支与 feature 分支都存在新的 commit 时,那么在 master 分支使用 git merge feature
会将 master 与 Feature 的最新 commit (E / H) 打包,在 master 分支提交为一个新的 commit (G)。
Rebase
图 3
图 3 ,当在 feature 分支使用 git rebase master
,会将 feature 分支的基变到 master 分支上。
注意:新 commit (F / H) 对比与旧提交,如图3 黄色的部分,其 sha 值不一致,说明 git rebase 是创建了新的提交。
图 4
图4,当在 master 分支使用 git rebase feature
,会将 master 分支的基变到 feature 分支上。
Rebase and merge
图 5
图 5 是由图 3 ,进行 merge 操作实现的,这是 merge 操作的另一种情况 :当 master 相对于 feature 没有新的提交时,在 master 分支上使用 git merge feature
会直接将 master 分支指向 feature 分支。
Squash and merge
图 6
squash 顾名思义是压缩,图 6 将 新分支的 commit (F / H) 进行打包压缩在与 master 分支进行 merge 操作。
优缺点
操作 | 优点 | 缺点 |
---|---|---|
merge | 简单直观 保留完整历史 |
合并提交冗余 分支历史不够整洁 |
rebase | 整洁的分支历史 清晰的提交历史 |
改变提交历史 容易产生合并冲突 |
squash | 清晰的提交历史 | 丢失提交信息 破坏历史信息 |