E---F---G---K----L'---M'---N' develop (where M', N' is chery pick from M, N)
/
A---B---C---D master
复制代码
除了修复 Sqaush Merge 引来的不测冲突以外, cherry-pick 还常用于从不稳定的开辟分支(不具备合并到主分支的条件)挑选个别需要告急发布的安全修复到稳定分支中, 这种场景合并没有意义, 由于合并反而会引入更多不需要的变更。
4. Rebase
最后一种常用的, 也是最强大(复杂)的合并方式是 Rebase。顾名思义, Rebase(变基) 即变更当前分支的根节点, 我们以如下拓扑结构为例介绍 Rebase 的流程:
E---F---G feature-xxx
/
A---B---C---D develop
复制代码
当我们开辟的基础分支已经落后于原分支时, 我们在提交接码前就应该使用 rebase :
➜ git rebase develop feature-xxx
复制代码
执行以上操作后, 拓扑结构将调整为如下所示:
E'---F'---G' feature-xxx
/
A---B---C---D develop
复制代码
其中, E’, F’, G’ 与原来的 E, F, G 内容完全一致, 本质上是在另一个根节点后重新应用原来的提交。
值得注意的是, rebase 后的分支是一定符合 fast-forward 的优化条件的, 这意味着 rebase merge 可以不创建无意义的合并节点, 有利于保持代码分支的可读性。
交互式 Rebase
Rebase 本质上是在另一个根节点上 重放 你的代码提交记录, 因此 rebase 不但仅具备变更根节点的能力, 还能压缩代码提交记录(squash), 修改代码提交信息(edit) 乃至可删除部门提交(drop)。我们可以通过启动一个交互式的 Rebase 会话来做到上述功能:
➜ git rebase -i HEAD~2
复制代码
执行上述指令后, Git 将打开一个编辑器, 依据指引操作即可:
pick 6b2e82f 2
pick a95710b 4
## 变基 7244a00..a95710b 到 7244a00(2 个提交)
#
## 命令:
## p, pick <提交> = 使用提交
## r, reword <提交> = 使用提交,但修改提交说明
## e, edit <提交> = 使用提交,进入 shell 以便进行提交修补
## s, squash <提交> = 使用提交,但融合到前一个提交
## f, fixup <提交> = 类似于 "squash",但丢弃提交说明日志
## x, exec <命令> = 使用 shell 运行命令(此行剩余部分)
## b, break = 在此处停止(使用 'git rebase --continue' 继续变基)