Ok, that's an old question and it already have accepted answer by @siride
, but that answer wasn't enough in my case, as --preserve-merges
forces you to resolve all conflicts second time. My solution based on the idea by @Tobi B
but with exact step-by-step commands
So we'll start on such state based on example in the question:
* 8101fe3 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
| |
| | * f5a7ca8 5 [origin/master]
| | * e7affba 4
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Note that we have 2 commits ahead master, so cherry-pick wouldn't work.
First of all, let's create correct history that we want:
git checkout -b correct-history # create new branch to save master for future
git rebase --strategy=ours --preserve-merges origin/master
We use --preserve-merges
to save our merge commit in history.
We use --strategy=ours
to ignore all merge conflicts as we don't care about what contents will be in that merge commit, we only need nice history now.
History will looks like that (ignoring master):
* 51984c7 Merge branch 'topic' [HEAD -> correct-history]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1
Let's get correct index now.
git checkout master # return to our master branch
git merge origin/master # merge origin/master on top of our master
We may get some additional merge conflicts here, but that's would only be conflicts from files changed between 8101fe3
and f5a7ca8
, but not includes already resolved conflicts from topic
History will looks like this (ignoring correct-history):
* 94f1484 Merge branch 'origin/master' [HEAD -> master]
|\
* | f5a7ca8 5 [origin/master]
* | e7affba 4
| * 8101fe3 Merge branch 'topic'
| |\
| | * b62cae6 2 [topic]
|/ /
* / eb3b733 3
|/
* 38abeae 1
The last stage is to combine our branch with correct history and branch with correct index
git reset --soft correct-history
git commit --amend
We use reset --soft
to reset our branch (and history) to correct-history, but leave index and working tree as is. Then we use commit --amend
to rewrite our merge commit, that used to have incorrect index, with our good index from master.
In the end we will have such state (note another id of top commit):
* 13e6d03 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1