A better svn diff

Since I started using git, every time I need to use Subversion again I suffer. The output of git diff is so nice compared to the one produced svn diff that it hurts. I've alredy been struggling with that previously.

Now I think I've achieved the perfect solution to make svn diff behave just like git diff. I've documented it in this post hoping to help other poor souls like me who still have to use Subversion now and then.

Step 1: install colordiff. It's installed on Debian, so the installation required me no effort at all.

Step2 (optional): configure colordiff to use your preferred set of colors. My ~/.colordiffrc contains the following, to match the same colors used by default by git diff:

banner=no
color_patches=no
plain=off
newtext=darkgreen
oldtext=darkred
diffstuff=white
cvsstuff=darkyellow

Step 3: create a script to be called by Subversion when running svn diff. In my case, I called it svn-diff and stored it in ~/bin (which is in my $PATH), but you can put it in /usr/local/bin or any other directory that is in your $PATH. The contents of ~/bin/svn-diff is the following:

#!/bin/sh
colordiff -u -L "${3}" -L "${5}" "${6}" "${7}" 

After creating the script, you need to make it executable:

$ chmod +x ~/bin/svn-diff

Step 4: tell Subversion to use your script instead of plain diff on svn diff. To do that, locate the "helpers" section in your Subversion configuration file (~/.subversion/config), and set the diff-cmd setting to the name you gave to your custom script (svn-diff in my case):

[helpers]
diff-cmd = svn-diff

There is only one thing missing with regard to git diff: the nice pager behaviour. Git invokes that system pager in a way that less will receives the options "-FRSX". These options make less exit imediately if the output fits in one terminal screen and output the ANSI sequences (and thus colors) generated by colordiff in raw format, among other things. I couldn't find a way to emulate this: since svn diff will call our custom  diff command once for each changed file, we can't call the pager inside svn-diff. A comprimise is doing svn diff | less -FRSX , or setting the LESS environment variable to 'FRSX' and doing simply svn diff | less.

That's it! Now you can almost forget you are using Subversion (until you need to do some merging).