git merge和git rebase有什么区别?
当前回答
我发现了一篇关于git rebase vs merge的非常有趣的文章,想在这里分享一下
如果你想看到完全相同的历史,你 应该使用归并。Merge保存历史,而rebase重写历史。 合并会向历史记录中添加一个新的提交 重基可以更好地简化复杂的历史记录,你可以通过交互的重基来改变提交历史。
其他回答
假设最初有3个提交,A,B,C:
然后开发人员Dan创建了提交D,开发人员Ed创建了提交E:
显然,这种冲突应该以某种方式解决。对此,有两种方法:
走:
提交D和E仍然在这里,但是我们创建了合并提交M,它继承了D和E的更改。然而,这创建了菱形,许多人对此感到非常困惑。
变基:
我们创建提交R,其实际文件内容与上面合并提交M的内容相同。但是,我们摆脱了提交E,就像它从未存在过一样(用圆点-消失线表示)。由于这种删除,E对于开发人员Ed来说应该是本地的,并且不应该被推送到任何其他存储库。rebase的优点是避免了菱形,历史保持良好的直线-大多数开发人员都喜欢这样!
Git rebase更接近于merge。rebase的区别是:
本地提交被临时地从分支中移除。 运行git pull 再次插入所有本地提交。
这意味着所有本地提交都被移动到最后,在所有远程提交之后。如果您遇到合并冲突,也必须解决它。
假设你已经在你的特性分支中提交了3次,当你想要将你的特性分支更改发送到主分支时。 你有两个选择
git merge:在这种情况下,主分支将只接收1次提交(合并3次提交) git rebase:在这种情况下,main branch将接收3次提交
merge和rebase的区别是什么?
阅读官方Git手册,它指出“rebase在另一个基本分支上重新应用提交”,而“merge将两个或多个开发历史连接在一起”。换句话说,merge和rebase之间的关键区别在于merge保留历史,而rebase重写历史。
让我们用一个并列的例子来说明这些陈述!
如上所述,合并操作通过创建一个新的合并提交(C7)将分支交织在一起,从而产生菱形非线性历史—本质上保留了发生的历史。通过将这个结果与rebase操作的结果进行比较,我们看到没有创建合并提交,相反,两个提交C5和C6只是被倒带并直接在C4上重新应用,保持历史记录的线性。
如果我们进一步仔细检查两次重新应用的提交,我们可以看到哈希值发生了变化,这表明rebase确实重写了历史。
值得注意的
每当你重新建立一个分支时,即使内容可能仍然相同,也总是会生成新的提交!也就是说,如果没有其他指针(分支/标记)引用它们,任何以前的提交最终(垃圾收集后)将从历史记录中删除。
能力越大,责任越大
我们已经看到了rebase如何重写历史,而merge如何保存历史。但从更广泛的意义上来说,这意味着什么呢?这两种操作有哪些可能性和潜在的缺陷?
冲突性的变更
比方说,您在尝试集成这些更改时遇到了一些严重的冲突。在合并场景中,您只需要在C7提交中直接解决一次冲突。另一方面,使用rebase,您可能被迫在每次提交(C5和C6)中解决类似的冲突,因为它们被重新应用。
发布分支
另一个与改基相关的潜在问题发生在您要改基的分支已经远程发布,而其他人的工作已经基于该分支进行了。然后,重新基于的分支可能会给所有相关方带来严重的困惑和头痛,因为Git会告诉您,您的分支同时处于领先和落后状态。如果发生这种情况,使用rebase标志拉出远程更改(git pull——rebase)通常可以解决问题。
此外,无论何时您要基于一个已经发布的分支进行重基,无论其他人是否基于它进行工作,您仍然需要强制推送它以将您的更新发送到远程服务器—完全覆盖现有的远程引用。
数据丢失(对您有利)
最后,由于rebase重写历史,而merge保留历史,因此在rebase时实际上可能会丢失数据。当重新应用新的提交时,旧的提交将被删除(最终,在垃圾收集之后)。同样的特性实际上是rebase如此强大的原因——它允许您在公开之前整理您的开发历史!
结论
而从潜在的数据丢失的角度来看,使用合并是安全的,并且感觉使用起来更直接。这里有一些提示,可以帮助您避免与改基相关的最常见问题。
不要对远程发布的分支进行重基… 除非你知道你是唯一一个在做这件事的人(而且你觉得推这件事很安全) 在重基之前,从将要重基的分支的顶端创建一个备份分支,因为它将允许您轻松地比较结果(一旦完成),并在必要时跳回到重基前的状态。
来源:以上节选自这篇关于“Git Merge和Rebase之间的区别-以及为什么你应该关心”主题的完整文章
我发现了一篇关于git rebase vs merge的非常有趣的文章,想在这里分享一下
如果你想看到完全相同的历史,你 应该使用归并。Merge保存历史,而rebase重写历史。 合并会向历史记录中添加一个新的提交 重基可以更好地简化复杂的历史记录,你可以通过交互的重基来改变提交历史。
推荐文章
- 如何查看一个分支中的哪些提交不在另一个分支中?
- 如何取消在github上的拉请求?
- HEAD和master的区别
- GIT克隆在windows中跨本地文件系统回购
- RPC失败;卷度传输已关闭,剩余未完成的读取数据
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 错误:您对以下文件的本地更改将被签出覆盖
- Git rebase—即使所有合并冲突都已解决,仍然会继续报错
- 在Git中,我如何知道我的当前版本是什么?
- 跟踪所有远程git分支作为本地分支
- 自定义SSH端口上的Git
- git如何显示不存在于.gitignore中的未跟踪文件
- Git错误:遇到7个文件应该是指针,但不是
- GitHub克隆与OAuth访问令牌
- 移动(或“撤销”)最后一个git提交到非暂存区域