Fixing commit TYPOs in git history with filter-branch

Last week, we tried at Atrapalo to migrate from our own git repository to Github. That should be easy, is just a matter of three commands already explained in Github’s guide. The main problem appears when you have some sort of issue with your commits, so messages like “invalid author email” raises when trying to push your changes.

For checking if your repository is ok, you can run git fsck. If everything is ok, nice, however, in our case, some error messages where there.

Screen Shot 2014-05-12 at 15.11.10

Let’s check those commits with issues with git log bca5308fa04b1d43e47de77fc264a770ba9d2522

Screen Shot 2014-05-12 at 15.13.48

Look at the author. There is an additional “<” that should not be there. That’s causing the problem. So we need to rewrite the history to update those commits. There are different options, but the ones that avoid remerging are based on filter-branch but cloning again your repo is a must. If you look to StackOverflow or Google, most of the scripts that are suppose to work are like:

$ git filter-branch --commit-filter '
        if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ];
        then
                GIT_AUTHOR_NAME="Scott Chacon";
                GIT_AUTHOR_EMAIL="[email protected]";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

But it didn’t work for us. So after talking with the GitHub guys, here’s the solution that worked like a charm.

git filter-branch -f -- --all

If take a closer look to git-filter-branch there is an interesting comment in the description:

If you specify no filters, the commits will be recommitted without any changes, which would normally have no effect. Nevertheless, this may be useful in the future for compensating for some Git bugs or such, therefore such a usage is permitted

The old commits will still be there, but pushing will push just the new ones. If you’re migrating and try to push –mirror, everything is pushed so it won’t work due to this old commits. An alternative could be git push –all -u origin

Hope it helps somebody.