git 为什么我用git rebase时同样的冲突又出现了?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31401754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 11:11:40  来源:igfitidea点击:

Why does the same conflict reappear when I use git rebase?

gitmergegit-mergegit-rebase

提问by NeoWang

I have read relevant questions about git merge and git rebase on SO, but I still cannot fully understand what is happening under the hood.

我已经阅读了关于 git merge 和 git rebase on SO 的相关问题,但我仍然无法完全理解幕后发生的事情。

Here is our branching situation:

这是我们的分支情况:

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

We have 2 feature branches that stem from master at different time, now we want to combine the 2 branches. We want to follow the first rebase then mergepractice, but when we rebase Feature A to Feature B, we get conflicts. That's expected, because both features (and master) have changes in the same areas. But the strange thing is that the same conflict keep reappearing after git rebase --continue. This drives us crazy, so we end up aborting the rebase, and use git merge. It turns out the conflicts are actually easy to resolve.

我们有 2 个不同时间源自 master 的特征分支,现在我们想合并这 2 个分支。我们想遵循这种first rebase then merge做法,但是当我们将 Feature A 变基为 Feature B 时,我们会遇到冲突。这是意料之中的,因为两个功能(和主)在相同的区域都有变化。但奇怪的是,同样的冲突在之后不断出现git rebase --continue。这让我们发疯,所以我们最终中止了 rebase,并使用git merge. 事实证明,冲突实际上很容易解决。

My question is two-fold:

我的问题有两个:

  1. Is git rebasesuitable for our situtation? Or is rebase only good for pulling in few (1 or 2) changes?
  2. What is happening under the hood that causes the same conflict to reappear again and again? My understanding is rebaseresolve conflicts one at a time, but by comparing which commit to what?
  1. git rebase适合我们situtation?还是 rebase 仅适用于引入少量(1 或 2)更改?
  2. 在幕后发生了什么导致同样的冲突一次又一次地重新出现?我的理解是一次rebase解决一个冲突,但是通过比较哪个提交到什么?

Relavant posts on SO:

SO上的相关帖子:

回答by Enrico Campidoglio

Is rebase suitable for your situation?

rebase 适合你的情况吗?

Based on the fact that Feature Aand Feature Bseem to be sharedbranches, I'd say no.

基于Feature AFeature B似乎是共享分支的事实,我会说no

Rebasing is a way to merge branches without having merge commits(i.e. commits that have two or more parents) making it appear as a linear history. It's best used to merge local branches, that is branches that only exist in your local repository and haven't been published to other people. Why? Because of at least two reasons:

变基是一种在没有合并提交(即具有两个或多个父项的提交)的情况下合并分支的方法,使其显示为线性历史。最好用于合并本地分支,即仅存在于本地存储库中且尚未发布给其他人的分支。为什么?因为至少有两个原因:

  1. Rebasing changes the commit IDs (i.e. the SHA-1hashes of their metadata). This means that once you push the rebased commits to the shared branch, they will appear as completely new commitsto anyone that fetches them on their local repo, even if they still contain the same changes. Now, if someone has added new commits on top of the old ones in the meantime, they will have to move them. This creates unnecessary confusion.

  2. When you merge public branches you often wantto have those merge commitsin order to be able to track how commits moved across branches. That information is lost with rebasing.

  1. 变基会更改提交 ID(即SHA-1其元数据的哈希值)。这意味着一旦您将重新提交的提交推送到共享分支,即使它们仍然包含相同的更改,对于在其本地存储库中获取它们的任何人,它们也会显示为全新的提交。现在,如果有人同时在旧提交之上添加了新提交,他们将不得不移动它们。这会造成不必要的混乱。

  2. 当您合并公共分支时,您通常希望拥有这些合并提交,以便能够跟踪提交是如何跨分支移动的。这些信息会因变基而丢失。

What's happening under the hood?

引擎盖下发生了什么?

Just a regular merge. The difference is that git rebasemerges one commit at a timeon top of the previous one starting from the common parent. git mergemerges two commits – with their entire set of changes – as a single operation, so you only have to resolve the conflicts once.

只是一个常规的合并。不同之处在于,从公共父级开始,一次在前一个提交之上git rebase合并一个提交git merge合并两个提交——连同它们的整个更改集——作为一个单一的操作,所以你只需要解决一次冲突。

Update: Resolving recurring conflicts

更新:解决重复发生的冲突

As @Jubobs pointed out in the comments, Git does have an automated solution for resolving conflicts that occur multiple times: git rerere, or "reuse recorded resolution".

正如@Jubobs 在评论中指出的那样,Git 确实有一个自动化的解决方案来解决多次发生的冲突:git rerere或“重用记录的解决方案”。

After you enable rererein your configuration file (rerere.enabled true) every time a merge conflict occurs, Git will record the state of the conflicting files before and afteryou merge them. Next time the same conflict occurs – a conflict involving the exact same lineson both sides of the merge – Git will automatically apply the same resolution it had recorded previously. It will also let you know about it in the merge output:

每次发生合并冲突时,在配置文件()中启用rererererere.enabled true,Git 都会记录合并前后冲突文件的状态。下次发生相同的冲突时——合并双方完全相同的行的冲突——Git 将自动应用它之前记录的相同解决方案。它还会在合并输出中让您知道它:

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

CONFLICT(内容):合并“somefile”中的冲突
使用以前的解决方案解决了“somefile”。

Here you can find more detailson how to deal with conflicts using git rerere.

在这里,你可以找到更多的细节上如何处理使用冲突git rerere