Skip to content

Instantly share code, notes, and snippets.

@philchristensen
Created August 10, 2010 20:20
Show Gist options
  • Save philchristensen/517913 to your computer and use it in GitHub Desktop.
Save philchristensen/517913 to your computer and use it in GitHub Desktop.
Color-Coded `svn status`

First there was: http://snipplr.com/view/15246/color-coded-svn-status

Then there was: http://snipplr.com/view/16540/color-coded-svn-status-v2

A few days ago, I found a handy script online that colorized the output of SVN status. It worked pretty well, but needed a little polish and a couple of tweaks to make it use more common Python idioms. As I continued to use it and fix bugs and inefficiencies, I ended up replacing nearly every line in the original, but it was still a great starting point.

Additional changes include ANSI word-wrapping, a configurable tab expansion feature (for better code alignment), the 'colorizedSubcommands' sequence so that only applicable commands get colorized, use of proper subprocess module calls so that piping through less will work (for example, try svn-color diff | less -r to see colorized diff output).

To use, stick it somewhere, make executable (chmod 755), and then add this to your .profile:

alias svn=/usr/local/bin/svn-color.py

I hope you find my modifications useful. You can modify the colors used by looking up the ANSI color codes for your preferred color scheme and editing the 'statusColors' dictionary. Here's a useful reference for ANSI color values:

http://www.ibm.com/developerworks/linux/library/l-tip-prompt/colortable.gif

Requires Python 2.4 or greater.

#!/usr/bin/env python
"""
Author: Saophalkun Ponlu (http://phalkunz.com)
Contact: phalkunz@gmail.com
Date: May 23, 2009
Modified: June 15, 2009
Additional modifications:
Author: Phil Christensen (http://bubblehouse.org)
Contact: phil@bubblehouse.org
Date: February 22, 2010
"""
import os, sys, re, subprocess
tabsize = 4
colorizedSubcommands = (
'status',
'add',
'remove',
'diff',
)
statusColors = {
"M" : "31", # red
"\?" : "37", # grey
"A" : "32", # green
"X" : "33", # yellow
"C" : "30;41", # black on red
"-" : "31", # red
"D" : "31;1", # bold red
"\+" : "32", # green
}
def colorize(line):
for color in statusColors:
if re.match(color, line):
return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
else:
return line
def escape(s):
s = s.replace('$', r'\$')
s = s.replace('"', r'\"')
s = s.replace('`', r'\`')
return s
passthru = lambda x: x
quoted = lambda x: '"%s"' % escape(x)
if __name__ == "__main__":
cmd = ' '.join(['svn']+[(passthru, quoted)[' ' in arg](arg) for arg in sys.argv[1:]])
output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
cancelled = False
for line in output.stdout:
line = line.expandtabs(tabsize)
if(sys.argv[1] in colorizedSubcommands):
line = colorize(line)
try:
sys.stdout.write(line)
except:
sys.exit(1)
@jerclarke
Copy link

Awesome dude! This is super useful for status. I still like colordiff a bit better for diffs (it makes changed lines bold which is a nice touch) but this script is definitely how status should work.

One thing I noticed is there's no color on the output of merges. Does that make sense to you? Would be a nice-to-have as to me the output of merge and status are equivalent so my brain wants colors in both. Status is the most important though :)

Thanks for keeping this modern and putting it in all the right places. Perfect use of Gist.

@philchristensen
Copy link
Author

Hi Jeremy!

Thanks, glad it's useful to you. I had gotten a couple of other improvement requests, so I ended up moving this to a repo so I could use pull requests.

https://github.com/philchristensen/svn-color

Feel free to send a pull request any time. I don't use SVN much anymore, and when I did I used merges very sparingly, but if I get a second I'll see about adding merge support myself...

Copy link

ghost commented Jun 23, 2013

Awesome!

@lionslair
Copy link

Great work

@yudjin87
Copy link

yudjin87 commented Jul 27, 2016

Hi,

Thnx for script. On my Ubuntu 16 output is a bit corrupted:
image

I changed from
return ''.join(("\001\033[", statusColors[color], "m", line, "\033[m\002"))
to
return ''.join(("\033[", statusColors[color], "m", line, "\033[m"))
and it works...

@jliebana
Copy link

Thanks for the gist and thanks to @yudjin87 for the fix!

@xergio
Copy link

xergio commented Mar 2, 2018

thank you @yudjin87 and @philchristensen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment