学习Git中的merge与rebase,了解它们如何影响代码历史和版本控制,以及如何在实际项目中选择使用。
chou403
/ Git
/ c:
/ u:
/ 7 min read
介绍
Git 中的 merge
和 rebase
是两种不同的合并分支的方法,它们在工作流和结果上有显著区别。
1. 概述
-
git merge
:- 将一个分支的更改合并到当前分支。
- 创建一个新的合并提交 (merge commit)。
- 保留分支的历史记录。
-
git rebase
:- 将一个分支的更改重新应用到另一个分支的顶端。
- 重写提交历史,不创建新的合并提交。
- 使提交历史更线性和整洁。
2. git merge
git merge
的工作方式是将两个分支的最新状态结合起来,创建一个新的合并提交。以下是一个例子:
假设你有以下分支结构:
A---B---C (main)
\
D---E (feature)
运行 git merge feature
时,Git 会创建一个新的合并提交:
A---B---C---F (main)
\ /
D---E (feature)
优点:
- 保留了完整的历史记录,清晰地显示了分支和合并的过程。
- 适合需要保留开发过程和决策点的项目。
缺点:
- 提交历史可能变得复杂,特别是在大量分支和合并的情况下。
3. git rebase
git rebase
的工作方式是将一个分支上的所有提交依次应用到另一个分支的顶端。以下是一个例子:
假设你有以下分支结构:
A---B---C (main)
\
D---E (feature)
运行 git rebase main
时,Git 会将 feature
分支的提交重新应用到 main
分支的顶端:
A---B---C---D'---E' (feature)
然后,如果你将 feature
分支合并回 main
,会得到一个线性的历史:
A---B---C---D'---E' (main)
优点:
- 提交历史变得线性和整洁,易于阅读和理解。
- 更适合保持干净的提交历史,特别是在 pull request 和代码评审时。
缺点:
- 重写历史(改变提交的哈希),在共享分支上使用时需要特别小心,可能会导致其他开发者的代码库冲突。
4. 选择使用 merge
还是 rebase
-
使用
merge
的场景:- 需要保留完整的开发历史和分支结构。
- 在团队协作中,尤其是需要明确记录分支点和合并点的场景。
- 大型项目中需要追踪各个分支的开发过程和决策点。
-
使用
rebase
的场景:- 需要一个干净,线性的提交历史,便于代码审查和管理。
- 在个人分支上整理提交历史,准备合并到主分支之前。
- 在 pull request 流程中保持提交记录的清晰和简洁。
5. 混合使用 merge
和 rebase
在实际开发中,常常结合使用 merge
和 rebase
来获得两者的优点。例如:
- 在自己的功能分支上使用
rebase
来保持提交历史的清晰。 - 在将功能分支合并到主分支时使用
merge
来保留完整的分支历史。
总结
git merge
: 合并分支,保留历史,创建合并提交。git rebase
: 重写历史,将提交应用到新的基点,创建线性历史。
选择 merge
还是 rebase
取决于你的工作流和对提交历史的要求。理解这两种方法的优缺点,有助于在不同的开发场景中做出最佳选择。
扩展知识
不建议在公共分支做rebase
一般来说,我们在工作中的开发模式都是基于分支开发,基于主干发布的模式。什么意思呢?
就是仓库中有一份主干的代码,线上运行的就是这套代码,当我们有需求要开发的时候,不会直接在主干上开发,而是基于主干拉一个分支出来,在分支中进行开发,开发好之后,再把这个分支的代码通过发布的方式合并到主干中。
在业内有一个rebase黄金法则:不要对已经提交到共享仓库(如远程仓库)的提交执行 rebase。
为什么要遵守这个黄金法则呢?
rebase会将所有的Main分支上的提交移动到Feature分支的顶端,问题是这个操作只发生在你自己的本地仓库中,所有的其他开发者是完全不感知的,因为他们是使用旧的Main分支创建的分支。
这时候如果我们的Feature变更被推送到远程仓库后,其他人的Feature想要在提交的时候,就会产生大量的冲突。
所以,在多人协作中,应该遵循以下指导原则:
- 在个人开发分支上进行 rebase:如果你在个人开发分支上进行 rebase,这不会对其他开发者产生影响,因为这个分支只属于你个人。
- 在共享仓库的主分支上使用 merge:在共享仓库的主分支(如 master 或 main)上,推荐使用 merge 来将开发的功能或修复合并回主分支。这样可以保留每个开发者的提交历史,易于跟踪和回溯。
- 协作时协商:如果有特殊情况需要在共享仓库的分支上进行 rebase,应该与其他开发者进行充分协商,并确保大家都知道并同意这个变更。