June 6, 2008

Removing things accidentally committed to git

So a few days ago I accidentally checked a bunch of my mp3s into the git repo for matschaffer.com. This blew out the size of .git and made clones a pain. So I wanted to remove it. I got some help from “jast” in the git IRC channel which set me straight.

In this case I had committed and pushed the mp3s, then committed one more change after that. So the bad commit was HEAD^^, but I also had HEAD^ that I wanted to keep.

Here’s what I did:

# Save any changes after the bad commit
git format-patch HEAD^

# Reset everything back to the bad commit
git reset --hard HEAD^^

# Remove the accidentally checked in file
git rm --cached thefile

# Amend the bad commit
git commit --amend

# Restore the other change from patch file
git am 

# Clean up.  Note this will eliminate any chance of undo-ing this process
git reflog expire --expire=0 --all
git prune --expire 0

# If you need to, you can force a push to correct the history on a remote repo as well
git push -f

After this my local .git was still pretty big (as was the server’s repo). But any new clones were nice and small. So I just created a new clone, and copied that up to the server via scp and all was well. It was a bit of a pain, but it was neat that git is capable of doing these sort of operations. Under subversion you’d need a system administrator to do this sort of stuff.