长话短说
如果您有任何疑问,请使用合并。
简答
变基和合并之间的唯一区别是:
- 历史记录的结果树结构(通常仅在查看提交图时才明显)是不同的(一个有分支,另一个没有)。
- 合并通常会创建一个额外的提交(例如树中的节点)。
- 合并和变基将以不同的方式处理冲突。Rebase 会一次呈现一个提交的冲突,而合并会一次呈现所有冲突。
因此,简短的答案是_根据您希望的历史记录选择变基或合并_。
长答案
选择使用哪种操作时应考虑几个因素。
您正在获取更改的分支是否与团队外部的其他开发人员共享(例如开源、公共)?
如果是这样,请不要变基。Rebase 会破坏分支,那些开发人员将拥有损坏/不一致的存储库,除非他们使用git pull --rebase
. 这是快速让其他开发人员感到不安的好方法。
您的开发团队技术如何?
Rebase 是一种破坏性操作。这意味着,如果您没有正确应用它,您可能会丢失已提交的工作和/或破坏其他开发人员存储库的一致性。
我曾工作过的团队中,开发人员都来自公司有能力聘请专门人员来处理分支和合并的时代。那些开发人员对 Git 不太了解,也不想了解太多。在这些团队中,我不会出于任何原因冒险推荐变基。
分支本身是否代表有用的信息
一些团队使用每个功能分支模型,其中每个分支代表一个功能(或错误修复,或子功能等)。在此模型中,分支有助于识别相关提交集。例如,可以通过恢复该分支的合并来快速恢复某个功能(公平地说,这是一种罕见的操作)。或者通过比较两个分支来区分特征(更常见)。变基会破坏分支,这并不简单。
我还曾在使用每个开发人员分支模型的团队中工作过(我们都经历过)。在这种情况下,分支本身不传达任何附加信息(提交已经有作者)。重新设定基准不会有什么坏处。
您可能出于某种原因想要恢复合并吗?
与恢复合并相比,恢复(如撤消)变基相当困难和/或不可能(如果变基有冲突)。如果您认为有可能想要恢复,请使用合并。
你在团队中工作吗?如果是这样,您愿意在这个分支上采取全有或全无的方法吗?
Rebase 操作需要使用相应的git pull --rebase
. 如果您自己工作,您也许能够记住应该在适当的时间使用哪个。如果你在一个团队中工作,这将很难协调。git pull --rebase
这就是为什么大多数变基工作流程建议对所有合并(以及所有拉取)使用变基。
常见的误区
合并会破坏历史(压缩提交)
假设您有以下合并:
有些人会说合并“破坏”了提交历史记录,因为如果您只查看主分支(A - D)的日志,您将错过 B 和 C 中包含的重要提交消息。
如果这是真的,我们就不会有这样的问题了。基本上,您会看到 B 和 C,除非您明确要求不要看到它们(使用 --first-parent)。这很容易自己尝试。
Rebase 允许更安全/更简单的合并
这两种方法的合并方式不同,但尚不清楚一种方法总是优于另一种方法,这可能取决于开发人员的工作流程。例如,如果开发人员倾向于定期提交(例如,当他们从工作地点转移到家庭时,他们可能每天提交两次),那么对于给定分支可能会有大量提交。其中许多提交可能看起来与最终产品完全不同(我倾向于对每个功能重构我的方法一次或两次)。如果其他人正在处理相关的代码区域,并且他们试图重新调整我的更改,那么这可能是一个相当乏味的操作。
Rebase 更酷/更性感/更专业
如果您喜欢使用别名rm
来rm -rf
“节省时间”,那么也许 rebase 适合您。
我的两分钱
我总是认为有一天我会遇到一个场景,Git rebase 是解决问题的很棒的工具。就像我认为我会遇到这样一个场景:Git reflog 是一个很棒的工具,可以解决我的问题。我使用 Git 已有五年多了。这还没有发生。
混乱的历史对我来说从来都不是问题。我从来不会像读一本令人兴奋的小说那样阅读我的提交历史。大多数时候我需要历史记录,无论如何我都会使用 Git Blame 或 Git Bisect。在这种情况下,合并提交实际上对我来说很有用,因为如果合并引入了问题,那对我来说就是有意义的信息。
更新(4/2017)
我觉得有必要提一下,尽管我的一般建议仍然有效,但我个人对使用 rebase 已经软化了。我最近与Angular 2 Material项目进行了很多互动。他们使用 rebase 来保持非常干净的提交历史记录。这使我能够非常轻松地查看哪些提交修复了给定的缺陷以及该提交是否包含在版本中。它是正确使用 rebase 的一个很好的例子。