How to avoid rebase hell when merge commits are in the way?

git, git-branch-sculpting, git-rebase, git-rewrite-history, rebase

Solution

I want to rebase and squash everything from feature so that I can advance master with a single commit of the feature being added.

This is exactly what the `--squash` option for `git merge` does. From the docs for git merge:

--squash

Produce the working tree and index state as if a real merge happened (except for the merge information), but do not actually make a commit or move the HEAD, nor record $GIT_DIR/MERGE_HEAD to cause the next git commit command to create a merge commit. This allows you to create a single commit on top of the current branch whose effect is the same as merging another branch (or more in case of an octopus).

(Emphasis mine)

Usage example:

git checkout master
git merge feature --squash
git commit

Problem

I've got the following situation in my git tree: ``` 1 -- 2 -- 3 -- 4 <-- master \ \ 5 -- 6 -- 7 -- 8 -- 9 <-- feature ``` I want to rebase and squash everything from feature so that I can advance master with a single commit of the feature being added. Being that commit 7 is already a merge that solves all the conflicts, I tried the following: ``` git rebase -i -p master ``` The only options that were given me here were commits 7, 8 and 9. "Makes sense", I thought, "since the merge already includes 5 and 6, they can just be discarded". I proceeded to squash 7, 8 and 9 in a single commit we'll call "789". (I know, I'm the creative type.) After this my tree looked like this: ``` 1 -- 2 -- 3 -- 4 <-- master \ 5 -- 6 -- 789 <-- feature ``` The presence of 5 and 6 in the same branch confused me, but again, since they were already included in 7 (which is now in 789), I could just discard them. So I `git rebase -i master` again and this time I discarded 5 and 6. However, conflicts arose here and there, so I aborted the whole thing. I am currently at that stage but my remote branch hasn't been updated, so I may as well do a reset to the original state. Which are the right steps that will land me where I want to without having to manually resolve all merge conflicts?

Original source