Git合并还是git变基?

3
我已经阅读了有关在Git中进行合并时git plain merge适用于某些情况,而git rebase适用于其他情况的内容。
但我不明白如何将rebase作为合并的替代方法。在rebase分支后仍需要进行合并,这很可能是一个快进合并。因此,据我所知,Rebase只是用来“保证”快进合并 - 它不能替代git合并。正确吗?

相关:https://dev59.com/qHRB5IYBdhLWcg3w9Lvn - tcooc
根据那篇文章,我的理解是如果你想要合并你的特性分支,那么在合并之后需要进行一次变基操作,所以变基不会替代合并。 - u123
Rebase 不仅仅用于“保证”快进合并,它还可以做更多的事情,包括重写历史。 - Shaun Luttin
4个回答

3
基本上就是这样了(或者说,至少是使用rebase 的一个原因)。它保证了快进式合并。(我发现在使用 git rerere时,与其合并相比,在变基时更容易解决冲突。)

我不能保证“快进合并”,但可以进行快进推送:在两种情况下(rebasemerge),你最终得到的提交是你正在合并的提交(或正在变基的提交)的严格后代,但如果你想让你的提交出现在上游,你需要将它们推送。如果你在git rebase之后尝试使用git merge,它不会是一个快进合并,而是一个无操作合并。 - Matthieu Moy

1
注意,无论是在重新基于提交的最后一个提交中,还是在合并后的最终合并提交中指向的快照都是相同的快照 - 只有历史记录不同。重新基于将更改按引入顺序从一条工作线重放到另一条工作线上,而合并则将端点合并在一起。以上是一个很好的总结!

没错。我想补充一下,git imerge 利用这个特性,可以像 rebase 一样解决单个提交的冲突,但是像 merge 一样记录最终结果。 - Matthieu Moy

0

我认为这两个操作在其操作方式上有根本的不同,但实现了类似的功能。

git rebase 将你的提交列表放在另一个分支的顶部。因此,冲突解决是按照你定义的顺序逐个提交完成的(如果使用 --interactive),如果你的提交不是完全正交的,每个提交都可能会产生冲突(即:每个提交可能无法应用,因为它们是单独应用的)。请注意,在 rebase 过程中,你还可以将多个提交合并成一个 - 这被称为压缩。

git merge 有不同的策略,它可以合并多个分支。 另外,查看合并帮助以查看你可以选择自动冲突解决策略(我将挑选一些并粘贴部分摘要):

  • ours:此选项通过优先选择我们的版本来强制解决冲突块。
  • octopus:这种情况下,它解决了多于两个头的情况,但拒绝进行需要手动解决的复杂合并。
  • subtree:这是一种修改过的递归策略。当合并树 A 和 B 时,如果 B 对应于 A 的子树,则首先将 B 调整为与 A 的树结构匹配,而不是在同一级别读取树。
说到这一点,只有在没有人查看您的更改时,rebase才是一种选择,因为它将更改提交哈希,并且合并始终适用。 还要注意,如果您拥有审查过程,则可以通过变基选项来更改更改历史记录以反映日志中的意图。

0

我认为这篇来自 Git Bucket 的论文会给你答案。

合并 vs. 变基

关于git rebase的第一件事是要理解它解决了与git merge相同的问题。这两个命令都旨在将一个分支中的更改集成到另一个分支中,只是它们的方式非常不同。
合并很好,因为它是一种非破坏性操作。现有的分支不会以任何方式更改。这避免了所有可能的rebase风险(下面讨论)。
另一方面,这也意味着每次需要合并上游更改时,特性分支都会有一个多余的合并提交。如果主分支非常活跃,这可能会使您的特性分支历史记录变得混乱。虽然可以通过高级git日志选项来缓解此问题,但这可能会使其他开发人员难以理解项目的历史记录。
rebase的主要好处是您可以获得更清晰的项目历史记录。首先,它消除了git merge所需的不必要的合并提交。其次,正如上图所示,rebase还会导致完全线性的项目历史记录 - 您可以一直跟随功能的顶部到项目的开始而没有任何分叉。这使得使用git log、git bisect和gitk等命令更容易浏览您的项目。
但是,这种纯净的提交历史有两个权衡:安全性和可追溯性。如果您不遵循rebase的黄金法则,则重写项目历史可能对您的协作工作流程造成灾难性影响。其次,重新设置会丢失合并提交提供的上下文 - 您无法看到上游更改何时合并到功能中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接