Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GIT - Rebase - How to deal with conflicts

I am working on a project that has two branches: master and feature

The feature branch was created some time ago and has numerous commits.

Since the feature branch was created there have been a couple of commits to master

At this point when I go to rebase off of master I get conflicts. I resolve them and then rebase --continue. Then I get conflicts again, and again resolve and rebase --continue. This happens over and over and many times it seems like they are the same conflicts that are appearing.

In my mind here is what is happening:

master(commits)->a->b feature(commits)->c->d->e->f->g

feature was branched from master->a and then all commits were created.

When I rebase it rewinds back to the begining of feature where it was branched from master applies master->b and then starts to apply feature->c at this point it has a conflict. I resolve (accepting the master changes) and continue. Now it tries to apply feature->d and finds the same conflict. Again I have to resolve and continue. This happens over and over.

For example here are the changes:

master->a
    <div id="foo">

master->b
    <div id="bar">

feature->c
    <div id="fubar">

feature->d
    //Nothing has changed, inherited from feature->c
    <div id="fubar">

I am assuming that when it reaches feature->c it says change foo to fubar and then it notices that foo is already changed to bar. I resolve to bar and then it does the same logic applying feature->d

My two questions:

1) Is my understanding of how git is working / dealing with commits/conflicts/rebasing correct?

2) How can I avoid having to resolve the same conflicts over and over again? I was thinking of squashing all of the commits on the feature branch so that there is only one to deal with. I was not sure if this was a good idea or exactly the best way to go about squashing in the scenario.

Note, this is a very simplified example. In reality I have a lot more commits and within each numerous files with numerous conflicts. Some of them appear to be the same throughout the rebase --continue process and some are new for each commit.

My end goal is to clean up this project as simply as possible (get the feature branch rebased off the current master). I do not care about the history of the commits.

like image 407
Shawn Northrop Avatar asked Feb 23 '17 19:02

Shawn Northrop


2 Answers

I do not care about the history of the commits.

If you really don't care about history, a git merge --squash is going to let you resolve all your conflicts at once and produce a single commit with all the changes.

To essentially do that --squash in-place, you could do something like this:

git branch -m feature feature-old
git checkout master -b feature
git merge --squash feature-old

After you resolve all conflicts (once), you will create a single commit on feature that has master as a parent.

That being said, I'm a fan of keeping history. Definitely try rerere first. You might also try an in-place rebase --interactive (e.g. git rebase -i $(git merge-base HEAD master)) to squash the fixup-type commits without completely eliminating all the discrete commits.

like image 79
dahlbyk Avatar answered Sep 23 '22 16:09

dahlbyk


I had a similar issue and it turned out that I was resolving conflicts with --ours when I should have been using --theirs.

The reason is that --ours is your changes in a merge, but in a rebase it is --theirs because git effectively removes your commits and replays copies of them.

So when you resolve a conflict with your version with a rebase do:

git checkout --theirs some.file git add some.file

but when resolving a conflict with your version with a merge do:

git checkout --ours some.file git add some.file

like image 31
William Myers Avatar answered Sep 23 '22 16:09

William Myers