为什么我在使用git rebase时,同样的冲突会再次出现?

73

我在SO上阅读了有关git合并和git变基的相关问题,但仍然无法完全理解发生了什么。

以下是我们的分支情况:

MASTER------------------------
        \        \
         \        \----Feature B---
          \                        \
           \-----Feature A----------\---Feature A+B

我们有两个从主分支(master)不同时间点起源的功能分支(Feature A和Feature B),现在希望将这两个分支合并。我们想要遵循"先变基再合并"(first rebase then merge)的做法,但当我们将Feature A变基到Feature B时,会出现冲突。这是预期的,因为这些功能分支(以及主分支)在同一区域进行了更改。但奇怪的是,在每次运行 "git rebase --continue" 后,同样的冲突都会重新出现。这让我们疯掉了,所以最终我们放弃了变基,使用了“git merge”。结果发现解决这些冲突其实很容易。

我的问题有两个方面:

  1. git rebase 是否适合我们的情况?或者说,变基只适合拉取少量(例如1或2个)的更改吗?
  2. 在幕后发生了什么导致相同的冲突一遍又一遍地出现呢? 我的理解是rebase一个接一个地解决冲突,但它比较哪个提交(commit),与什么进行比较?

相关的Stack Overflow帖子:


你确定这是同一个冲突吗(同一文件,同一行,同一更改),还是同一文件+同一行但有新的不同更改,或者只是同一文件但冲突的行范围不同? - quetzalcoatl
1
嗯..抱歉问一个这么简单的问题 - 冲突出现后,你纠正了它后记得执行git add conflicted.file吗?如果没有,git 就不会注意到修复提交,而git rebase --continue会重新引发该文件未解决的冲突。 - quetzalcoatl
它们并不完全相同的冲突,但肯定涉及相同的行,我确信没有像经常发生的冲突那样有很多改变会触及到这个区域。在执行 git rebase continue 命令之前,我们需要先执行 add conflicted.file - NeoWang
1
可能是Git rebase --preserve-merges fails的重复问题。 - jub0bs
关于第二点,您可能想要激活rerere - jub0bs
1个回答

78

重置是否适合您的情况?

考虑到Feature AFeature B似乎是共享分支,我会说不适合

重置是一种合并分支的方法,无需产生合并提交(即具有两个或多个父项的提交),使其看起来像线性历史。它最适用于合并本地分支,也就是仅存在于本地存储库中未发布给其他人的分支。为什么?因为至少有两个原因:

  1. 重置更改提交ID(即元数据的SHA-1哈希)。这意味着一旦将重置提交推送到共享分支后,在其本地repo上获取它们的任何人都会将它们显示为全新的提交,即使它们仍包含相同的更改。现在,如果某人同时添加了旧的提交之上的新提交,他们将不得不移动它们。这会导致不必要的混乱。

  2. 当您合并公共分支时,通常需要那些合并提交,以便能够跟踪提交如何在分支之间移动。使用重置会丢失该信息。

底层发生了什么?

只是一个常规的合并。不同之处在于,git rebase从共同的父项开始,逐个将提交合并到前一个提交上。git merge将两个提交(带有它们的全部更改)作为单个操作合并,因此您只需要解决一次冲突。

更新:解决重复冲突

正如@Jubobs在评论中指出的那样,Git确实有一种自动解决多次发生的冲突的解决方案:git rerere,或者叫"重用已记录的解决方案"。
当你在配置文件中启用rererererere.enabled true)后,每次出现合并冲突时,Git都会记录冲突文件的状态在合并之前和之后。下次出现相同的冲突时,即涉及合并的完全相同行时,Git将自动应用先前记录的相同解决方案。它还会在合并输出中通知您:

CONFLICT (content): Merge conflict in 'somefile'
Resolved 'somefile' using previous resolution.

在这里您可以找到更多有关如何使用git rerere解决冲突的更多详细信息

17
我认为你的答案应该提到“rerere”。 - jub0bs
3
值得一提的是,有些支持 rebase 的人认为将所有冲突解决更改都包含在一个合并提交中是非常糟糕的事情。有人可能会认为,相比于一个巨大的合并提交中包含已解决的所有更改,将孤立的冲突解决作为一系列提交出现更好。 - ely
我总是对那些重复的冲突感到困惑。通常情况下,当有人将develop或其他特性分支合并到他们的特性分支中,并在一段时间后尝试重新基于develop时,我会遇到这种情况。出于某种原因,我认为这是由合并提交创建的分叉引起的。这可能完全是错误的。但解决这种困惑一劳永逸肯定是好的——你是说重复的冲突是因为Git当前应用的提交已更改了我们第一次冲突解决所影响的同一行吗? - Rustam Issabekov

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