ChatGPT解决这个技术问题 Extra ChatGPT

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

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.

Here is our branching situation:

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

Given 2 feature branches that stem from master at different times, we now want to combine the 2 branches. We want to follow the first rebase then merge practice, but when we rebase Feature A onto 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 keeps 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.

My question is two-fold:

Is git rebase suitable for our situation? Or is rebase only good for pulling in a few (e.g., 1 or 2) changes? What is happening under the hood that causes the same conflict to reappear again and again? My understanding is rebase resolves conflicts one at a time, but which commit does it compare, and what does it compare it to?

Relavant posts on SO:

Why do I have to resolve the same conflict over and over?

https://stackoverflow.com/questions/7241678/how-to-prevent-lot-of-git-conflicts-when-git-rebasing-lot-of-commits\

git rebase resolve conflicts again and again?

Are you sure that this is the same conflict (same file, same lines, same changes), or is same-file + same-lines but new different changes to them, or is it just the same file but conflicted line ranges are different?
um.. and sorry for asking such a simple thing - after the conflict first occurred, and after you corrected it, did you remember to do a git add conflicted.file ? if not, git wouldn't notice fixing the commit and git rebase --continue would reraise the file as not resolved yet
They are not exactly the same conflict, but surely involve the same lines, and I am sure there are not as many changes (as the recurring conflicts) that touch this area. And we do add conflicted.file before git rebase continue.
possible duplicate of Git rebase --preserve-merges fails
Regarding 2., you probably want to activate rerere.

E
Enrico Campidoglio

Is rebase suitable for your situation?

Based on the fact that Feature A and Feature B seem to be shared branches, I'd say 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:

Rebasing changes the commit IDs (i.e. the SHA-1 hashes of their metadata). This means that once you push the rebased commits to the shared branch, they will appear as completely new commits to 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. When you merge public branches you often want to have those merge commits in order to be able to track how commits moved across branches. That information is lost with rebasing.

What's happening under the hood?

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

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".

After you enable rerere in your configuration file (rerere.enabled true) every time a merge conflict occurs, Git will record the state of the conflicting files before and after you merge them. Next time the same conflict occurs – a conflict involving the exact same lines on 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:

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

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


I think your answer should mention rerere.
Just a side note, some who are in favor of rebasing would consider the fact that all conflict resolution changes are contained in a single merge commit to be a very bad thing. One might argue that it's better to see isolated conflict resolutions appearing as a sequence of commits, instead of one big ball of resolved changes in a single commit.
I always got confused about those repeating conflicts. I normally had it when somebody merged develop or some other feature branch into their feature branch and attempted to rebase onto develop after some time. For some reason i thought that its because of a fork that a merge commit creates. Which is probably totally wrong. But it would be good to solve this confusion once and for all - are you saying that a repeating conflict happens because the commit that git is currently applying has changed the same line that was affected by our first conflict resolution?