1. 概述

在使用 Git 作为版本控制系统(VCS)时,我们可能会采用各种分支策略,但最终通常需要将某个功能分支的变更合并到主分支(main)中。

本文将介绍两种常见的分支合并方式:git mergegit rebase,并分析它们在实际开发中的区别与适用场景。

2. Git Rebase

简单来说,git rebase 会将你的整个功能分支“移动”到主分支的最新提交之上,为原分支上的每一个提交创建新的提交

我们通过一个示例来理解 rebase 的工作原理:

先克隆仓库并创建两个测试分支:

git clone <your_repository_here>
git branch testBranch1
git branch testBranch2

testBranch1 上添加文件并提交:

git checkout testBranch1
git add .
git commit -m "Add new feature A"
git push --set-upstream origin testBranch1
git log

此时查看提交日志,你会看到如下内容(图片示意):

git Rebase Feature Branch1 Commit Log

接下来尝试将该分支 rebase 到 main 分支上:

git rebase main

因为此时 main 分支没有任何提交,所以不会有任何变化。

然后我们将其合并到 main 分支:

git checkout main
git merge testBranch1
git push
git log

结果如下图所示:

git Merge Feature Branch1 Rebase Merge Commit Log

可以看到,提交 ID 没有发生变化,这与 fast-forward 合并类似。

接下来我们看 testBranch2 的情况。我们先在该分支上做提交:

git checkout testBranch2
git add .
git commit -m "Add new feature B"
git push --set-upstream origin testBranch2
git log

执行结果如下图:

git Rebase Feature Branch2 Commit Log

再尝试将它 rebase 到 main 分支上:

git rebase main

此时会看到如下提示(图片):

git Rebase Feature Branch2 Post Commit

由于 main 分支已经有提交,因此 rebase 会基于 main 的最新提交重新应用 testBranch2 的提交。

现在我们将 testBranch2 合并到 main 分支:

git checkout main
git merge testBranch2
git push
git log

查看提交日志:

git Rebase Feature Branch2 Rebase Merge Commit Log

可以看到,提交 ID 已经改变。这说明 rebase 是基于原提交重新生成新提交的过程。

我们可以通过以下命令查看 Git 的提交图:

git log --graph --oneline

输出如下图所示:

git Rebase Merge Branch Graph Final

📌 结论:rebase 会生成新的提交,历史是线性的

3. Git Merge

git merge 的工作方式是找到两个分支的共同祖先提交,然后分别将两个分支的提交依次“应用”在该祖先上,从而完成合并。

我们继续使用前面创建的仓库和分支来演示。

先在 testBranch1 上提交一个文件:

git checkout testBranch1
git add .
git commit -m "Add feature A"
git push --set-upstream origin testBranch1
git log

提交日志如下图所示:

Git Merge Feature Branch1 Commit Log

接着将它合并到 main 分支:

git checkout main
git merge testBranch1
git push
git log

结果如下图:

git Merge Feature Branch1 Merge Commit Log

HEAD 指针已经指向 main 分支,但提交 ID 没有变化,这是 fast-forward 合并的典型特征。

现在我们再看一个更复杂的情况:main 和 feature 分支都有新的提交。

testBranch2 上提交一个文件:

git checkout testBranch2
git add .
git commit -m "Add feature B"
git push --set-upstream origin testBranch2
git log

提交日志如下图:

Git Merge Feature Branch2 Commit Log

然后将其合并到 main 分支:

git checkout main
git merge testBranch2
git log

输出如下图:

git Merge Feature Branch2 Merge Commit Log

⚠️ 注意:此时 Git 创建了一个新的“合并提交”,并且 HEAD 指向这个合并提交。

我们再次查看提交图:

git log --graph --oneline

输出如下图:

Git Merge Branch Graph

📌 结论:merge 会保留原始提交,并创建一个合并提交,历史是非线性的

4. 使用场景对比

场景 推荐操作 原因
希望提交历史清晰、线性 rebase 避免合并提交,历史更干净
多人协作,分支已推送到远程 merge 避免 rebase 后提交 ID 变化导致冲突
本地开发分支,未推送 rebase 保持提交历史整洁
需要保留合并记录 merge 适合审计或需要明确合并点的场景

⚠️ 注意:不要对已经推送到远程仓库的提交使用 rebase! 因为 rebase 会生成新的提交 ID,可能导致协作混乱。

5. 总结

对比维度 git merge git rebase
提交历史 非线性,保留原始提交 线性,生成新提交
合并方式 合并两个分支的变更 将分支“移动”到另一个分支顶端
是否保留提交 ID
是否适合协作分支
是否生成合并提交

📌 建议:

  • 本地开发时可以使用 rebase,让提交历史更清晰;
  • 多人协作、已推送到远程的分支建议使用 merge,避免提交混乱;
  • 永远不要对公共分支(如 main)使用 rebase!

如果你还在纠结该用 merge 还是 rebase,记住一句话:

✅ “Use merge to preserve history, and rebase to rewrite history.”


原始标题:Difference Between git merge and rebase