git merge和git rebase有什么区别?
git merge
git rebase
umuewwlo1#
假设最初有3个提交,A,B,C:
A
B
C
然后,开发人员Dan创建了提交D,开发人员Ed创建了提交E:
D
E
显然,这种冲突应该以某种方式解决。为此,有两种方法:
合并:
提交D和E仍然在这里,但是我们创建了合并提交M,它继承了来自D和E的修改。然而,这会创建一个 * 菱形 * 形状,很多人会觉得很混乱。
M
重建:
我们创建了提交R,它的实际文件内容与上面的合并提交M完全相同。但是,我们删除了提交E,就像它从未存在过一样(由点-消失线表示)。由于这种消除,E对于开发人员艾德应该是本地的,并且不应该被推送到任何其他存储库。和历史保持良好的直线-大多数开发人员喜欢!
R
h9vpoimq2#
就我个人而言,我并不觉得标准的图表技术很有帮助--箭头似乎总是指向错误的方向。(它们通常指向每个提交的“父”,这最终会在时间上倒退,这很奇怪)。用文字来解释:
由于我不明白的原因,Git的GUI工具从来没有做过很多努力来更干净地呈现合并历史,抽象出单独的合并。所以如果你想要一个“干净的历史”,你需要使用rebase。我似乎记得读过一些程序员的博客文章,他们只使用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件事”帖子的作者 *)
master
zpjtge223#
因为你的特性工作可以呈现为一个大的补丁文件(也就是diff),而不需要“解释”多个父分支:至少有两个,来自一个合并,但可能更多,如果有几个合并。***与合并不同,多个重基不加起来。***(另一个大优点)
2w3kk1z54#
Git rebase更接近于merge。rebase的区别在于:
所以这意味着你所有的本地提交都被移到最后,在所有的远程提交之后。如果你有合并冲突,你也必须解决它。
uoifb46i5#
为方便明白可以看到我的身影。重定基会改变提交哈希,所以如果你想避免很多冲突,只要在分支完成/完成稳定时使用重定基。
8cdiaqws6#
merge
rebase
阅读官方Git手册,它指出**“rebase在另一个基础分支上重新应用提交”,而“merge将两个或多个开发历史连接在一起”**。换句话说,merge和rebase的关键区别在于merge保留历史,而rebase重写历史。让我们用一个并列的例子来说明这些陈述!
如上所述,merge操作通过创建新的单个合并提交将分支交织在一起(C7),导致菱形的非线性历史记录-本质上保留了发生的历史记录。通过将此结果与rebase操作的结果进行比较,我们可以看到没有创建合并提交,相反,两个提交C5和C6被简单地倒带并直接在C4的顶部重新应用,保持历史线性。如果我们进一步仔细检查这两个重新应用的提交,我们可以看到哈希值已经改变,这表明rebase确实重写了历史。
每当你rebase一个分支,新的提交总是会产生,即使内容可能仍然是相同的!也就是说,任何以前的提交最终(后垃圾收集)将从历史中删除,如果没有其他指针(分支/标记)引用它们。权力越大责任越大我们已经看到了rebase是如何改写历史的,而merge是如何保存历史的。但是,从更广泛的意义上讲,这意味着什么呢?这两种操作会带来哪些可能性和潜在的缺点呢?
恩怨的变更
比如说,你在整合变更时遇到了一些严重的冲突。在合并的情况下,你只需要解决一次冲突,直接在C7提交中解决。另一方面,在rebase的情况下,你可能会被迫在每次提交(C5和C6)中解决类似的冲突。
已发布的分支
另一个与rebase相关的潜在问题是当你的分支已经被远程发布,并且其他人已经基于它进行了工作。那么,你的分支可能会给所有相关方造成严重的混乱和头痛,因为Git会告诉你你的分支同时领先和落后。如果发生这种情况,使用rebase标志(git pull --rebase)拉取远程更改通常可以解决这个问题。此外,无论何时,当您对一个已经发布的分支进行重定基时,不管是否有其他人基于它进行工作,您仍然需要强制推送它,以便将您的更新发送到远程服务器--完全覆盖现有的远程引用。
数据丢失(对您有利)
最后,由于rebase重写了历史,而merge保留了它,所以在rebase时可能会丢失数据。当新的提交被重新应用时,旧的提交会被删除(最终,在垃圾收集后)。事实上,这同样是rebase如此强大的特性--它允许你在公开之前整理你的开发历史!结论虽然merge从潜在数据丢失的Angular 来看是安全的,而且使用起来更直接。下面是一些可以帮助您避免与rebase相关的最常见问题的提示。
7uzetpgm7#
我发现了一篇关于gitrebase与merge的非常有趣的文章,我想把它分享给大家
svmlkihl8#
假设你已经在特性分支中做了3次提交,当你想把特性分支的更改发送到主分支时,你有两个选择
8条答案
按热度按时间umuewwlo1#
假设最初有3个提交,
A
,B
,C
:然后,开发人员Dan创建了提交
D
,开发人员Ed创建了提交E
:显然,这种冲突应该以某种方式解决。为此,有两种方法:
合并:
提交
D
和E
仍然在这里,但是我们创建了合并提交M
,它继承了来自D
和E
的修改。然而,这会创建一个 * 菱形 * 形状,很多人会觉得很混乱。重建:
我们创建了提交
R
,它的实际文件内容与上面的合并提交M
完全相同。但是,我们删除了提交E
,就像它从未存在过一样(由点-消失线表示)。由于这种消除,E
对于开发人员艾德应该是本地的,并且不应该被推送到任何其他存储库。和历史保持良好的直线-大多数开发人员喜欢!h9vpoimq2#
就我个人而言,我并不觉得标准的图表技术很有帮助--箭头似乎总是指向错误的方向。(它们通常指向每个提交的“父”,这最终会在时间上倒退,这很奇怪)。
用文字来解释:
由于我不明白的原因,Git的GUI工具从来没有做过很多努力来更干净地呈现合并历史,抽象出单独的合并。所以如果你想要一个“干净的历史”,你需要使用rebase。
我似乎记得读过一些程序员的博客文章,他们只使用rebase,而其他人从不使用rebase。
示例
我试着用一个简单的例子来解释这一点。假设你项目中的其他人正在开发用户界面,而你正在编写文档。如果没有rebase,你的历史可能看起来像这样:
也就是说,在文档提交过程中进行合并和UI提交。
如果您将程式码重新设定为master的基底,而不是合并它,它看起来会像这样:
你所有的提交都在顶部(最新的),后面是
master
分支的其余部分。(* 免责声明:我是另一个答案中提到的“我讨厌Git的10件事”帖子的作者 *)
zpjtge223#
合并
重定基准
**总结:**如果可能的话,重定基几乎总是更好的。使重新集成到主分支更容易。
因为你的特性工作可以呈现为一个大的补丁文件(也就是diff),而不需要“解释”多个父分支:至少有两个,来自一个合并,但可能更多,如果有几个合并。***与合并不同,多个重基不加起来。***(另一个大优点)
2w3kk1z54#
Git rebase更接近于merge。rebase的区别在于:
所以这意味着你所有的本地提交都被移到最后,在所有的远程提交之后。如果你有合并冲突,你也必须解决它。
uoifb46i5#
为方便明白可以看到我的身影。
重定基会改变提交哈希,所以如果你想避免很多冲突,只要在分支完成/完成稳定时使用重定基。
8cdiaqws6#
merge
和rebase
之间有什么区别?阅读官方Git手册,它指出**“rebase在另一个基础分支上重新应用提交”,而“merge将两个或多个开发历史连接在一起”**。换句话说,merge和rebase的关键区别在于
merge
保留历史,而rebase
重写历史。让我们用一个并列的例子来说明这些陈述!
如上所述,
merge
操作通过创建新的单个合并提交将分支交织在一起(C7),导致菱形的非线性历史记录-本质上保留了发生的历史记录。通过将此结果与rebase
操作的结果进行比较,我们可以看到没有创建合并提交,相反,两个提交C5和C6被简单地倒带并直接在C4的顶部重新应用,保持历史线性。如果我们进一步仔细检查这两个重新应用的提交,我们可以看到哈希值已经改变,这表明
rebase
确实重写了历史。值得注意
每当你
rebase
一个分支,新的提交总是会产生,即使内容可能仍然是相同的!也就是说,任何以前的提交最终(后垃圾收集)将从历史中删除,如果没有其他指针(分支/标记)引用它们。权力越大责任越大
我们已经看到了rebase是如何改写历史的,而merge是如何保存历史的。但是,从更广泛的意义上讲,这意味着什么呢?这两种操作会带来哪些可能性和潜在的缺点呢?
恩怨的变更
比如说,你在整合变更时遇到了一些严重的冲突。在合并的情况下,你只需要解决一次冲突,直接在C7提交中解决。另一方面,在rebase的情况下,你可能会被迫在每次提交(C5和C6)中解决类似的冲突。
已发布的分支
另一个与rebase相关的潜在问题是当你的分支已经被远程发布,并且其他人已经基于它进行了工作。那么,你的分支可能会给所有相关方造成严重的混乱和头痛,因为Git会告诉你你的分支同时领先和落后。如果发生这种情况,使用rebase标志(git pull --rebase)拉取远程更改通常可以解决这个问题。
此外,无论何时,当您对一个已经发布的分支进行重定基时,不管是否有其他人基于它进行工作,您仍然需要强制推送它,以便将您的更新发送到远程服务器--完全覆盖现有的远程引用。
数据丢失(对您有利)
最后,由于rebase重写了历史,而merge保留了它,所以在rebase时可能会丢失数据。当新的提交被重新应用时,旧的提交会被删除(最终,在垃圾收集后)。事实上,这同样是rebase如此强大的特性--它允许你在公开之前整理你的开发历史!
结论
虽然
merge
从潜在数据丢失的Angular 来看是安全的,而且使用起来更直接。下面是一些可以帮助您避免与rebase
相关的最常见问题的提示。***来源:***以上摘录摘自此主题的完整文章:Differences Between Git Merge and Rebase — and Why You Should Care
7uzetpgm7#
我发现了一篇关于gitrebase与merge的非常有趣的文章,我想把它分享给大家
svmlkihl8#
假设你已经在特性分支中做了3次提交,当你想把特性分支的更改发送到主分支时,你有两个选择
git merge
:在这种情况下,主分支将只接收1个提交(合并3个提交)git rebase
:在这种情况下,主分支将接收3次提交