Tuesday, 19 May 2015

Normalise line endings in Git repository without external tools

As it happens, I recently »inherited« a Git repository. It turned out that all files had been submitted with Windows line endings, also known as CRLF. Since the core.autocrlf wasn't set, they were stored as such in the repository.

Since it was a private repository that wasn't published anywhere (that I knew of or cared about), I decided to rewrite its history as a first step. I wanted to use Git's own conversion rather than relying on external tools such as fromdos, so I activated it using

$ git config core.autocrlf input
Then I wrote a small shell script called readd.sh that re-adds the current commit and triggers Git's line-ending conversion:
#!/bin/sh

git rm --cached -r .
git add -f .
The -f option to add ensures that even files that are in .gitignore are re-added. Yes, they even managed to submit ignored files into their repository...

As a last step, I used filter-branch to process every commit and apply my script.

$ git filter-branch --tree-filter "$HOME/readd.sh" -- --all

Since it was a very small repository, the entire process took only a matter of seconds, and I was left with a clean state with normalised line endings.