572

git merge和有什么区别git rebase

4

7 回答 7

951

假设最初有 3 个提交,A, B, C

美国广播公司

然后开发人员 Dan 创建了 commit D,开发人员 Ed 创建了 commit E

ABCDE

显然,这种冲突应该以某种方式解决。为此,有两种方法:

合并

ABCDEM

两者都提交DE仍然在这里,但是我们创建了合并提交M,它继承了D和的更改E。然而,这会产生钻石形状,许多人对此感到非常困惑。

重新定位

ABCDER

我们创建 commit R,其实际文件内容与M上面的合并提交相同。但是,我们摆脱了 commit E,就像它从未存在过一样(用点表示 - 消失线)。由于这种删除,E应该是开发人员 Ed 本地的,并且不应该被推送到任何其他存储库。rebase 的优点是避免了菱形,并且历史保持良好的直线 - 大多数开发人员都喜欢这一点!

于 2013-05-21T09:22:05.143 回答
168

就我个人而言,我不觉得标准的图表技术很有帮助——箭头似乎总是指向错误的方向。(它们通常指向每个提交的“父”,最终会在时间上倒退,这很奇怪)。

用文字来解释:

  • 当你将你的分支rebase到他们的分支上时,你告诉 Git 让它看起来好像你干净地检查了他们的分支,然后从那里开始做所有的工作。这样就形成了一个干净的、概念上简单的更改包,可供某人查看。当他们的分支上有新的更改时,您可以再次重复此过程,并且您将始终在其分支的“尖端”上得到一组干净的更改。
  • 当您他们的分支合并到您的分支中时,此时您将两个分支历史联系在一起。如果您稍后再进行更多更改,您将开始创建一个交错的历史线索:他们的一些更改,我的一些更改,他们的一些更改。有些人觉得这很混乱或不受欢迎。

由于我不明白的原因,Git 的 GUI 工具从未付出太多努力来更清晰地呈现合并历史,抽象出单个合并。所以如果你想要一个“干净的历史”,你需要使用 rebase。

我似乎记得曾经阅读过使用 rebase 的程序员和其他从不使用 rebase 的程序员的博客文章。

例子

我将尝试用一个简单的例子来解释这一点。假设您项目中的其他人正在处理用户界面,而您正在编写文档。如果没有变基,你的历史可能看起来像:

Write tutorial
Merge remote-tracking branch 'origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md

也就是说,在文档提交中间进行合并和 UI 提交。

如果您将代码重新定位到 master 而不是合并它,它将如下所示:

Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger

您的所有提交都在顶部(最新),然后是master分支的其余部分。

免责声明:我是另一个答案中提到的“我讨厌 Git 的 10 件事”帖子的作者

于 2014-08-12T14:38:16.603 回答
51

虽然接受和最受好评的答案很好,但我还发现尝试仅用文字解释差异很有用:

合并

  • “好的,我们的存储库有两种不同的开发状态。让我们将它们合并在一起。两个父母,一个孩子。”</li>

变基

  • “将主分支(无论其名称)的更改提供给我的功能分支。假装我的功能工作是在以后开始的,实际上是在主分支的当前状态下开始的。”</li>
  • “重写我的更改历史以反映这一点。” (需要强制推送它们,因为通常版本控制就是篡改给定的历史记录)
  • “很可能——如果我所做的更改与我的工作无关——历史实际上不会有太大变化,如果我逐个查看我的提交差异(你可能还会想到‘补丁’)。”</li>

总结:如果可能,rebase 几乎总是更好。使重新集成到主分支更容易。

因为?➝ 您的功能工作可以呈现为一个相对于主分支的大“补丁文件”(又名 diff),而不必“解释”多个父级:至少两个,来自一个合并,但可能更多,如果有进行了几次合并。与合并不同,多个变基不会累加。(另一个大优点)

于 2015-09-23T07:10:43.333 回答
29

Git rebase 更接近于合并。变基的区别是:

  • 本地提交会暂时从分支中删除。
  • 运行 git pull
  • 再次插入所有本地提交。

这意味着在所有远程提交之后,您的所有本地提交都将移到最后。如果你有合并冲突,你也必须解决它。

于 2016-11-29T12:53:40.990 回答
15

为了便于理解可以看我的图。

Rebase 将更改提交哈希,因此如果您想避免很多冲突,只需在该分支完成/完成时使用 rebase 作为稳定。

在此处输入图像描述

于 2018-06-08T07:22:59.583 回答
6
于 2021-03-26T08:05:01.997 回答
3

我发现一篇关于 git rebase vs merge的非常有趣的文章,想在这里分享

  • 如果你想看到和它发生的完全一样的历史,你应该使用合并。Merge 保留历史,而 rebase 重写它。
  • 合并为你的历史添加了一个新的提交
  • 变基更好地简化复杂的历史,您可以通过交互式变基来更改提交历史。
于 2019-11-28T00:02:55.767 回答