Rebase doesn’t normally preserve merge commits without --preserve-merges
Ok, so I’m not exactly sure what would happen if you tried to squash a merge commit using an interactive rebase with --preserve-merges
…but this is how I would remove the merge commit in your case and make your history linear:
-
Rebase everything before the merge commit on top of the remote branch.
-
Cherry-pick or rebase everything after the merge commit on top of the previously rebased commits.
If you only have 1 commit after the merge commit
So in terms of commands, that would look something like this:
# Reset to commit before merge commit
git reset --hard <merge>^
# Rebase onto the remote branch
git rebase <remote>/<branch>
# Cherry-pick the last commit
git cherry-pick 1abcd
If you have more than 1 commit after the merge commit
# Leave a temporary branch at your current commit
git branch temp
# Reset to commit before merge commit
git reset --hard <merge>^
# Rebase onto the remote branch
git rebase <remote>/<branch>
# Cherry-pick the last commits using a commit range.
# The start of the range is exclusive (not included)
git cherry-pick <merge>..temp
# Alternatively to the cherry-pick above, you can instead rebase everything
# from the merge commit to the tip of the temp branch onto the other
# newly rebased commits.
#
# You can also use --preserve-merges to preserve merge commits following
# the first merge commit that you want to get rid of...but if there were
# any conflicts in those merge commits, you'll need to re-resolve them again.
git rebase --preserve-merges --onto <currentBranch> <merge> temp
# These next steps are only necessary if you did the rebase above,
# instead of using the cherry-pick range.
#
# Fast-forward your previous branch and delete temp
git checkout <previousBranch>
git merge temp
git branch -d temp
Documentation
-
Official Linux Kernel git-cherry-pick(1) Manual Page
-
Official Linux Kernel git-rebase(1) Manual Page