Git 支持的合并方式只有两种:ff 和 no-ff。

  • 如果当前分支是并入 commit 的祖先,执行 ff commit。直接将当前分支快进到指定 commit 而不产生 Merge commit。

    Diagram
  • 如果无法执行 ff merge 或者强制使用了 --no-ff ,处理冲突并合并代码后会产生一个 Merge commit。如果对 Merge commit 执行 reset 操作,则相当于 merge 被取消。

    Diagram

根据功能上还有下面几种合并方式:

  • rebase merge。合并前在并入分支上执行 rebase 以执行 ff merge。这是 线性提交历史 要求的做法。

  • squash merge。合并时添加参数 --squash 。这将导致并入分支上的 commit 被压缩成一个被合并。

线性提交历史

通过确保代码合并总是以 ff 的形式进行合并,能够避免产生 Merge commit,从而形成整洁的、单一线性的提交历史。线性提交历史具备一些优点。例如:

  • 线性提交历史比非线性提交历史更易于理解。

  • 更易于回溯更改。

  • 易于跟踪错误。例如有利于 git bitset 的使用。

  • 易于回滚更改。revert merge commit 会导致整个合并被回滚,而线性历史不会。

线性提交历史的关键之处在于在合并之前总是执行 rebase 以确保当前分支已经包含了被并入分支的所有 commit。从而在合并时执行 ff 合并。然而,由于 rebase 自身的问题,这可能带来一些问题:

  • rebase 会更改当前分支的历史 commit id。

  • rebase 需要解决每个 commit 带来的冲突。而 no-ff 只需要解决最终冲突即可。

Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx