1. 概述
在使用 Git 作为版本控制系统(VCS)时,我们可能会采用各种分支策略,但最终通常需要将某个功能分支的变更合并到主分支(main)中。
本文将介绍两种常见的分支合并方式:git merge
和 git 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
此时查看提交日志,你会看到如下内容(图片示意):
接下来尝试将该分支 rebase 到 main 分支上:
git rebase main
因为此时 main 分支没有任何提交,所以不会有任何变化。
然后我们将其合并到 main 分支:
git checkout main
git merge testBranch1
git push
git 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
执行结果如下图:
再尝试将它 rebase 到 main 分支上:
git rebase main
此时会看到如下提示(图片):
由于 main 分支已经有提交,因此 rebase 会基于 main 的最新提交重新应用 testBranch2
的提交。
现在我们将 testBranch2
合并到 main 分支:
git checkout main
git merge testBranch2
git push
git log
查看提交日志:
✅ 可以看到,提交 ID 已经改变。这说明 rebase 是基于原提交重新生成新提交的过程。
我们可以通过以下命令查看 Git 的提交图:
git log --graph --oneline
输出如下图所示:
📌 结论: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
提交日志如下图所示:
接着将它合并到 main 分支:
git checkout main
git merge testBranch1
git push
git 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
提交日志如下图:
然后将其合并到 main 分支:
git checkout main
git merge testBranch2
git log
输出如下图:
⚠️ 注意:此时 Git 创建了一个新的“合并提交”,并且 HEAD 指向这个合并提交。
我们再次查看提交图:
git log --graph --oneline
输出如下图:
📌 结论: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.”