Rewriting Git history

The other day I made about 30 commits to a project without realizing my editor was adding spaces to the files even though they mostly contained tabs. I really couldn’t care less whether files have tabs or spaces, but consistency is the important thing, so I decided to rewrite my history using git’s filter-tree option.

This command checks out each original revision, and makes the changes specified, then commits that as a new revision. In this case I replace a tab with 4 spaces in every .cs file. I start from origin/master and go up to the currently checked out commit (head):

git filter-branch --tree-filter "find . -name '*.cs' -exec sed -i -e 's/\t/    /g' {} \;" origin/master..HEAD

You can run an arbitrary script (perhaps run it from a different file if it’s longer than this though!). Here’s another example using git diff to check which “.cs” files were new or modified in the range I’m rewriting, which I then pipe to sed and replace a tab with four spaces.

git filter-branch --tree-filter "git diff --name-status master HEAD | egrep ^[AM] | grep .cs | cut -f2 | xargs sed -i \"s/\t/    /g\"" master..HEAD

This one won’t deal well with files that are created anywhere except the first commit. I’ll leave that as an exercise for the reader 😉


About GrahamTheCoder

I'm a C# developer based in Cambridge hoping blogging will achieve some or all of the following. Help me organise my thoughts. Practice writing things other than code. Give me a place to refer people to when I'm trying to make a long winded point. I welcome comments and constructive criticism, and hope to look back at my written opinions in the future and laugh at my own naivety.
This entry was posted in Note to self. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s