11th May 2009 20:31:20 by Richard Bennett
svn diff doesn't colour diff output, and all the fixes on the web are dodgey hacks and wrapper code that don't really do what most of these authors really wanted in the first place: svn diff to be coloured.
So here's my solution:
Enter the following into a file called "svn-coloured-diff.php" in your home directory and chmod it to 755 (be careful of newlines and line wrapping caused by web site layout):
#!/usr/local/bin/php -q
<?
// option to temporarily turn colour off
$showColour = true;
// option to temporarily force colour into pipes as well as tty
$forceColour = false;
// grab the paths to diff
$fn2 = array_pop($argv);
$fn1 = array_pop($argv);
// remove our path
unset($argv[0]);
// we're left with the switches and their parms, which with labels (-L) could be broken
// across multiple array elements, so make a string, rip out the labels and leave the
// remaining switches.
$labels = array();
preg_replace('#-L (.*?)(?= -L|$)#se','$labels[] = "$1"',join(' ',$argv));
$switches = preg_replace('#-L (.*?)(?= -L|$)#s','',join(' ',$argv));
exec('diff '.$switches.' --label "'.$labels[0].'" --label "'.$labels[1].'" '.$fn1.' '.$fn2,$diffLines);
// configure text styling for screen only (not for piping or non-TTY)
if ((posix_isatty(STDOUT) || $forceColour) && $showColour) {
$addedStyle = chr(27).'[1;42m';
$removedStyle = chr(27).'[41m';
$resetStyle = chr(27).'[0m';
} else {
$addedStyle = $removedStyle = $resetStyle = '';
}
// display it
foreach ($diffLines as $line) {
if (substr($line,0,1) == '+') {
echo $addedStyle.$line.$resetStyle;
} elseif (substr($line,0,1) == '-') {
echo $removedStyle.$line.$resetStyle;
} else {
echo $line;
}
echo "\n";
}
?>
Next edit ~/.subversion/config and find the line:
# diff-cmd = diff_program (diff, gdiff, etc.)
Replace it with this:
diff-cmd = /home/your-user-name/svn-coloured-diff.php
There's two booleans at the top of the script to make it a little more flexible. $showColour allows you to turn off all the colour coding, in case you need the original diff output; and $forceColour forces it to always include ANSI colour coding, when normally it doesn't colour code if there's no screen (i.e. you're piping or something similar).