为啥我使用 git rebase 时会再次出现相同的冲突?
Posted
技术标签:
【中文标题】为啥我使用 git rebase 时会再次出现相同的冲突?【英文标题】:Why does the same conflict reappear when I use git rebase?为什么我使用 git rebase 时会再次出现相同的冲突? 【发布时间】:2015-10-02 19:15:53 【问题描述】:我已经阅读了关于 SO 上 git merge 和 git rebase 的相关问题,但我仍然无法完全理解幕后发生的事情。
这是我们的分支情况:
MASTER------------------------
\ \
\ \----Feature B---
\ \
\-----Feature A----------\---Feature A+B
给定 2 个在不同时间源自 master 的特征分支,我们现在想要合并这 2 个分支。我们想遵循first rebase then merge
的做法,但是当我们将功能 A 重新定位到功能 B 时,我们会遇到冲突。这是意料之中的,因为两个特性(和主特性)在相同区域都有变化。但奇怪的是,同样的冲突在git rebase --continue
之后不断重现。这让我们发疯,所以我们最终中止了 rebase,并使用git merge
。事实证明,这些冲突其实很容易解决。
我的问题有两个:
git rebase
适合我们的情况吗?还是 rebase 仅适用于引入一些(例如 1 或 2 个)更改?
幕后发生了什么导致相同的冲突一次又一次地出现?我的理解是rebase
一次解决一个冲突,但它比较的是哪个提交,它与什么比较?
关于 SO 的相关帖子:
Why do I have to resolve the same conflict over and over? https://***.com/questions/7241678/how-to-prevent-lot-of-git-conflicts-when-git-rebasing-lot-of-commits\ git rebase resolve conflicts again and again?【问题讨论】:
您确定这是相同冲突(相同文件、相同行、相同更改),还是相同文件+相同行但对它们进行了新的不同更改,还是只是同一个文件但冲突的行范围不同? 嗯.. 很抱歉问了这么简单的问题 - 在第一次发生冲突之后,在你纠正它之后,你还记得做一个git add conflicted.file
吗?如果没有,git 不会注意到修复提交,git rebase --continue
会将文件重新提升为尚未解决
它们不是完全相同的冲突,但肯定涉及相同的行,而且我确信没有那么多的变化(如反复出现的冲突)触及这个领域。我们在git rebase continue
之前做add conflicted.file
。
Git rebase --preserve-merges fails的可能重复
关于2.,你可能想激活rerere
。
【参考方案1】:
rebase 适合你的情况吗?
基于Feature A
和Feature B
似乎是共享 分支这一事实,我会说不。
变基是一种合并分支的方法无需合并提交(即具有两个或更多父级的提交),使其显示为线性历史。最好用于合并本地分支,即仅存在于本地存储库中且尚未发布给其他人的分支。为什么?至少有两个原因:
变基会更改提交 ID(即其元数据的 SHA-1
哈希)。这意味着,一旦您将重新定位的提交推送到共享分支,它们将显示为完全新提交,任何在其本地存储库中获取它们的人,即使它们仍然包含同样的变化。现在,如果有人同时在旧提交之上添加了新提交,他们将不得不移动它们。这会造成不必要的混乱。
当您合并公共分支时,您经常希望拥有这些合并提交,以便能够跟踪提交如何跨分支移动。这些信息会因变基而丢失。
幕后发生了什么?
只是一个常规的合并。不同之处在于git rebase
将一次提交合并到前一个提交之上,从公共父级开始。 git merge
将两个提交(连同它们的整个更改集)合并为一个操作,因此您只需解决一次冲突。
更新:解决反复出现的冲突
正如@Jubobs 在 cmets 中指出的那样,Git 确实有一个自动解决方案来解决多次发生的冲突:git rerere
,或“重用记录的解决方案”。
在你的配置文件(rerere.enabled true
)中启用rerere后,每次发生合并冲突时,Git都会记录冲突文件的状态之前和之后你合并它们。下次发生同样的冲突时——涉及合并两侧的完全相同的行的冲突——Git 将自动应用它之前记录的相同分辨率。它还会在合并输出中让你知道它:
CONFLICT(内容):“somefile”中的合并冲突 使用以前的分辨率解决了“somefile”。
您可以在此处找到more details,了解如何使用git rerere
处理冲突。
【讨论】:
我认为你的回答应该提到rerere
。
顺便说一句,一些支持变基的人会认为所有冲突解决更改都包含在单个合并提交中是一件非常糟糕的事情。有人可能会争辩说,最好将孤立的冲突解决方案视为一系列提交,而不是在单个提交中解决一大堆已解决的更改。
我总是对那些重复的冲突感到困惑。当有人将开发或其他功能分支合并到他们的功能分支中并在一段时间后尝试重新定位到开发时,我通常会拥有它。出于某种原因,我认为这是因为合并提交创建了一个分叉。这可能是完全错误的。但是一劳永逸地解决这种混乱会很好 - 你是说重复冲突发生是因为 git 当前正在应用的提交更改了受我们第一次冲突解决方案影响的同一行?以上是关于为啥我使用 git rebase 时会再次出现相同的冲突?的主要内容,如果未能解决你的问题,请参考以下文章
如何解决与 2 个远程仓库的 git merge/rebase 冲突?
Git执行"git rebase -i HEAD~xxx"报错:git rebase fatal: Needed a single revision invalid upst