Updated answer for 2020:
You can force git rebase -i to stop at the merge commit via the break command (added in Git 2.20). You can then edit the merge commit as desired via git commit --amend.
Detailed steps:
- Run
git rebase -i --rebase-merges $ancestor_of_merge_commit - Find the merge commit you want to edit in the todo list.
- Insert a new line after the merge commit that contains only
break(orb). - Save your changes and exit your editor. Git rebase will check out the merge commit, print something like the following, then return you to your prompt:
Stopped at fb91fab (Merge branch 'foo' into bar) - Use
git commit --amendto edit the merge commit as desired. - Run
git rebase --continuewhen you are done editing the merge commit.
Alternative approach if you do not have any merge commits after the commit you want to edit:
- Run
git rebase -i $id_of_merge_commit - Insert a new line at the top of the todo list that contains only
break(orb). - Save your changes and exit your editor. Git rebase will check out the merge commit, print something like the following, then return you to your prompt:
Stopped at fb91fab (Merge branch 'foo' into bar) - Use
git commit --amendto edit the merge commit as desired. - Run
git rebase --continuewhen you are done editing the merge commit.
Original answer from 2012 (pre-break):
Git does not make it easy to do interactive rebases when merges are involved. The -p option uses the -i mechanism internally, so mixing the two doesn’t really work.
However, git rebase is just an automated way to do lots of cherry-picks. You can replicate its behavior by manually cherry-picking to get a bit more control over the process. It’s less convenient and more prone to human error, but possible.
This is the approach I suggest:
- use
git rebaseto get to the commit after the merge (the child of the merge) - use
git reset --hard HEAD^to manually get to the merge - use
git commit --amendto repair the merge - use
git cherry-pickto get back to the commit after the merge - use
git rebase --continueto finish
Here are the specific steps:
- Note the SHA1 ID of the merge commit you want to modify. For discussion, suppose it is
deadbeef. - Note the SHA1 ID of the commit right after the merge commit you want to modify (the merge commit’s child). Suppose it is
facef00d. - Run
git rebase -i deadbeef. - Select
facef00dfor editing. - When rebase returns you to a prompt to edit
facef00d, rungit reset --hard HEAD^. You should now be atdeadbeef(git rev-parse HEADshould printdeadbeef). - Make your edits to fix the incorrect merge conflict and use
git addto stage them. - Run
git commit --amendto fuse the staged fix with the bad merge commit. The result will now have a different SHA1 (notdeadbeef). - Run
git cherry-pick facef00dto apply the changes made byfacef00dto the fixed merge commit. - Run
git rebase --continueto finish.