--ff(Fast-forward)
Fast-forward 是指 Master 合并 Feature 时候发现 Master 当前节点一直和 Feature 的根节点相同,没有发生改变,那么 Master 快速移动头指针到 Feature 的位置,所以 Fast-forward 并不会发生真正的合并,只是通过移动指针造成合并的假象
git checkout master
git merge feautre556
Updating a1ec682..38348cc
Fast-forward
....... | 2+++
1 file changed, 2 insertions(+)
如果你注意上面的文字的话,你会发现 git 帮你自动执行了 Fast-forward 操作
合并前:
合并后:
通常功能分支(feature556) 合并 master 后会被删除,通过下图可以看到,通过 Fast-forward 模式产生的合并可以产生干净并且线性的历史记录:
--no-ff(non-Fast-forward)
通常,当合并的分支跟 master 不存在共同祖先节点的时候,这时候在 merge 的时候 git 默认无法使用 Fast-forward 模式
举个例子,master 分支已经比 feature001 快了2个版本,master 已经没办法通过移动头指针来完成 Fast-forward,所以在 master 合并 feature001 的时候就不得不做出真正的合并,真正的合并会让 git 多做很多工作,具体合并的动作如下:
- 找出 master 和 feature001 的公共祖先,节点 c1,c6, c3 三个节点的版本 (如果有冲突需要处理)
- 创建新的节点 c7,并且将三个版本的差异合并到 c7,并且创建 commit
- 将 master 和 HEAD 指针移动到 c7
补充:大家在
git log看到很多类似:Merge branch 'feature001' into master的 commit 就是 non-Fast-forward 产生的。
合并前:
合并后:
总结
- -ff 自动合并模式:当合并的分支为当前分支的后代的,那么会自动执行
--ff (Fast-forward)模式,如果不匹配则执行--no-ff(non-Fast-forward)合并模式 - --no-ff 非 Fast-forward 模式:在任何情况下都会创建新的 commit 进行多方合并(即使被合并的分支为自己的直接后代)
- --ff-only Fast-forward 模式:只会按照
Fast-forward模式进行合并,如果不符合条件(并非当前分支的直接后代),则会拒绝合并请求并且退出 - --squash 模式:当一个合并发生时,从当前分支和对方分支的共同祖先节点之后的对方分支节点,一直到对方分支的顶部节点将会压缩在一起,注意:这种方式不移动HEAD,不会提交。需要进行一次额外的commit来“总结”一下,然后完成最终的合并
- --no-commit 模式:会将两个分支的差异合并,但不会立即创建一个新的提交。这允许用户在合并后检查和调整合并结果,然后再决定是否提交。如果提交也需要额外的一次commit