How do you fix a bad merge, and replay your good commits onto a fixed merge?

git, git-filter-branch, git-rewrite-history, git-rm

Solution

Please don't use this recipe if your situation is not the one described in the question. This recipe is for fixing a bad merge, and replaying your good commits onto a fixed merge.

Although `filter-branch` will do what you want, it is quite a complex command and I would probably choose to do this with `git rebase`. It's probably a personal preference. `filter-branch` can do it in a single, slightly more complex command, whereas the `rebase` solution is performing the equivalent logical operations one step at a time.

Try the following recipe:

# create and check out a temporary branch at the location of the bad merge
git checkout -b tmpfix <sha1-of-merge>

# remove the incorrectly added file
git rm somefile.orig

# commit the amended merge
git commit --amend

# go back to the master branch
git checkout master

# replant the master branch onto the corrected merge
git rebase tmpfix

# delete the temporary branch
git branch -d tmpfix

(Note that you don't actually need a temporary branch, you can do this with a 'detached HEAD', but you need to take a note of the commit id generated by the `git commit --amend` step to supply to the `git rebase` command rather than using the temporary branch name.)

Problem

I accidentally committed an unwanted file (`filename.orig` while resolving a merge) to my repository several commits ago, without me noticing it until now. I want to completely delete the file from the repository history. Is it possible to rewrite the change history such that `filename.orig` was never added to the repository in the first place?

Original source

Related problems