Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: rebasing a conflicted merge commit

After finishing working on a topic branch, I merged the topic branch into master like following:

          o---*---o---o topic
         /             \
o---o---o---*---o---o---+ master

The commits marked with '*' modified the same code, hence merging lead to merge conflicts that were resolved in the merge commit (marked with '+').

While I merged and resolved the conflicts, my colleague pushed new commits to master (marked as 'n'), resulting in following history:

          o---*---o---o topic
         /             \
o---o---o---*---o---o---+ master
                    \
                     n---n origin/master

Now, pushing my local master branch of course leads to an error, as it's no fast-forward-push, so I have two choices:

  1. Throw away my work, reset master to origin/master and redo the merge. I'd like to avoid that as I'd have to resolve the conflicts all over again.

  2. Rebase master onto origin/master and push. Here comes my problem: doing this rebase (even when using the -p switch) does not work smoothly, the merge commit shows the same conflicts again, even though the new commits ('n') didn't change anything touched by the topic branch. So I'd have to resolve the conflicts again during the rebase and would have the same result as with option 1.

What I'd like to achieve is rebasing the merge commit '+' without having to resolve the conflicts again:

          o---*---o---o-------- topic
         /                     \
o---o---o---*---o---o---n---n---+ master & origin/master

Edit:

The rerere switch is enabled but didn't seem to help in any way; do I have to do anything more than setting config.rerere to true to fix my problem?

Edit 2:

Merging the merge-commit ('+') to origin/master would also work (as proposed in the comments and an answer) but would lead to a kind of ugly history which I'd like to avoid by having one merge commit only.

like image 919
rhabarbersaft Avatar asked Feb 20 '15 11:02

rhabarbersaft


1 Answers

The first way would be the best. Undo your merge and redo it to get your colleague's changes into the merge commit. But you don't need to throw the changes away.

Since you know that your colleague's changes didn't affect the files that you resolved the conflicts in. You could create a new branch (we'll call it conflict-fix) from your current state of master. Reset your branch and redo the merge.

Rather than using git mergetool or whatever editor that you use. You can bring the file into master from your other branch using git checkout conflict-fix -- <file names>. git add the files and commit to complete the merge. Then you can delete the conflict-fix branch.

This is fairly easy to do and will result in the single merge commit that you are looking for plus allowing you to push your changes. If the new commits affected the files that you resolved the conflicts in you would have to redo them anyways.

EDIT

I am not completely familiar with git rerere but that should have worked. However based on your comment, you should not need to rebase. You would still have undone the merge commit, git fetch the updates and re-performed the merge. You would have to just call the git rerere command and it would have resolved the conflicts in the files for you. With your tree looking like this:

          o---*---o---A topic
         /             \
o---o---o---*---o---o---+ master
                 \
                  n---n origin/master

You would do the following:

git reset --hard A
git checkout master
git pull
git merge topic
git rerere
//Fix other conflicts
git push

And you should end up with:

          o---*---o---o-------- topic
         /                     \
o---o---o---*---o---o---n---n---+ master & origin/master

There should be no need to rebase anything.

http://git-scm.com/docs/git-rerere

like image 185
Schleis Avatar answered Oct 22 '22 23:10

Schleis