Subversion enhancements for your commandline
I am mainly using subversion to manage nearly all of my development projects as well as a lot of other stuff which benefits from revisioning. Because I mainly use vim for all my editing needs, I am working on the commandline a lot. This includes the commandline client "svn". I integrated some little bash helper functions, to make the svn output even more readable and useful, into my workflow over the time.
I decided to put all those little helpers together into one bash function, which wraps around the svn command. To easy the handling of it even more.
Some of these "enhancements" are written by me some are written by others, like Kore Nordmann.
Enhancements
You might ask yourself what enhancements could be made to the svn command line utility as it is quite perfect. Let me give you a listing of improvements done.
Diff
The diffing is improved by utilizing the colordiff utility to colorize its output for better readability.
Furthermore less is used for displaying to make scrolling inside larger diffsets easier.
${SVN} diff ${arguments}|colordiff|lessUpdate
The update function of svn is enhanced thanks to a blog article I discovered some years ago. Graeme Mathieson provides a bash function in it which displays the log entries for the changes made since your last update.
# This snippet is taken from a blog post found on the net. My
# thanks go out to the author of it.
# http://woss.name/2007/02/01/display-svn-changelog-on-svn-up/
# I have slightly modified it to better suit my needs.
local old_revision=`${SVN} info ${arguments} | awk '/^Revision:/ {print $2}'`
local first_update=$((${old_revision} + 1))
${SVN} up ${arguments}
local new_revision=`${SVN} info ${arguments} | awk '/^Revision:/ {print $2}'`
if [ ${new_revision} -gt ${old_revision} ]; then
svn log -v -rHEAD:${first_update} ${arguments}
else
echo "No changes."
fiStatus
Kore Nordmann gave me a sed one liner some days ago which colorizes the status output of the subversion client. Furthermore it filters out svn external links, which are normally just a distraction from the things that changed.
# My thanks for this snippet go to Kore Nordmann
# (http://kore-nordmann.de)
${SVN} st --ignore-externals ${arguments} | grep -v '^X' | sed -e 's/^\?.*$/^[[1;34m\0^[[m/' -e 's/^!.*$/^[[1;31m\0^[[m/' -e 's/^A.*$/^[[1;32m\0^[[m/' -e 's/^M.*$/^[[1;33m\0^[[m/' -e 's/^D.*$/^[[0;31m\0^[[m/'Log and Blame
After Kore send the status colorizer to me I decided to create similar expressions for log and blame/praise.
${SVN} log ${arguments}|sed -e 's/^-\+$/^[[1;32m\0^[[m/' -e 's/^r[0-9]\+.\+$/^[[1;31m\0^[[m/'${SVN} blame ${arguments}|sed -e 's/^\(\s*[0-9]\+\s*\)\([^ ]\+\s*\)\(.*\)$/^[[1;32m\1^[[m^[[1;31m\2^[[m\3/'Putting it all together
I put all of the above features together in one simple bash function. You can download it here. Just copy the contents of the downloaded file to your .bashrc file. No further work should be needed. The enhancements will just magically work after you loaded a new shell.
Please make sure you use a proper editor to copy the contents of the file to your .bashrc file, because otherwise the color escape codes may not be inserted correctly.
Update
After reading Kores comment about the problems which may be introduced by simple wrapping around the svn command. I put together a file containing the nameing scheme sugested by him in is comment. You can download it here. Use it instead of the other scripts linked above if you often need the default functionality of the svn command.
If you are using the svn wrapper command you may still call the original unmodified svn binary at any time using its full path. This would be "/usr/bin/svn" in most of the cases. I still think using the wrapper is the way to go, because you will most likely use the enhancements a lot more than needing the original output. Therefore I prefer calling the svn binary in those rare cases directly.
Kore on Sun, 15 Mar 2009 00:56:12 +0100
I actually don't really like modifying the behaviour of the original program. That's why the wrapper functions I use are named "svnup", "svndiff", etc.
Link to commentYou overwrite the original behaviour, why might make it harder to use the original tool for some tasks. Like displaying changes in externals, even this is seldomly required...
Another thing which will stop working are simple snippets like: `svn st | grep '^?' | xargs svn add` because of the appended color codes.
Jakob on Sun, 15 Mar 2009 03:42:15 +0100
I see your point. Until now I actually used the same naming scheme you are presenting. For this blog post I decided to pimp the calling code a little because I remembered how hard it has been for me at the beginning to use svnup instead of svn up which I typed as some kind of reflex.
Link to commentIn most of the cases you will want to use the enhanced version. If you really need to get the unmodified behaviour or output calling the svn binary using its full path "/usr/bin/svn" will do the trick.
I think considering the number of times you will need the default output instead of the new one this is a useful solution.
Nevertheless you are right the user should be able to choose between the two different calling behaviours. Therefore I put up a second version of the bashrc functions using the naming scheme you sugested.
greetings
Jakob
Matthew Turland on Sun, 15 Mar 2009 19:48:26 +0100
The alternative version has a syntax error. svnlog() is missing an opening {.
Link to commentJakob on Sun, 15 Mar 2009 20:52:54 +0100
Thanks. It's fixed now. I guess I should not write bash scripts at 4 o'clock in the morning ;)
Link to commentgreetings
Jakob
Evan on Sun, 15 Mar 2009 22:53:36 +0100
You may also want to take a look at a post I did here (http://www.dotevan.com/2008/11/08/de-annoyifying-subversion-externals/). It allows you to default externals on the status to off, but also allows you to switch it back on.
Link to commentAs a side note, I couldn't get the colorization to work in my terminal -- it just displays the escape codes, rather than the colors, even though my terminal is set to display ansi color.
Jakob on Mon, 16 Mar 2009 01:20:17 +0100
Evan if you want to show the externals using my solution just call "/usr/bin/svn st" instead of "svn st". Unfortunately a side effect would be, that the coloring than does not work also.
Link to commentConcerning the problem with the escape codes. Have you copy&pasted different sections of the blog article or did you copy&paste from one of the bashrc files I provided. In most cases there are problems with the escape sequences copied correctly. "^[" is actually one character not to. Because it only stands for the ESC character. If it is not the right escape char in your document try to replace it manually. In vim for example you can insert the needed escape character by pressing <STRG-V> followed by <ESC> in insert mode.
greetings
Jakob
Robin Speekenbrink on Mon, 16 Mar 2009 09:45:05 +0100
Jakob,
Link to commentNice addons! Although i seem to be running into a problem using colordiff... Your colorization works like a charm on the svnlog, svnst etc but when using svndiff the escape codes seem to show...
I've installed the colordiff and standalone it works like a charm but when adding |less to it, it breaks the coloring...
Anyway to fix this?
Lukas on Mon, 16 Mar 2009 11:02:10 +0100
One of the things that annoys me with svn diff is that there is no way to ignore whitespace changes, which is why I have defined an alias:
Link to commentalias svndiff='svn diff --diff-cmd `which diff` -x "-u -w"'
Robin Speekenbrink on Mon, 16 Mar 2009 18:44:20 +0100
An update (and fix) for my previous comment on the breaking of colours in svndiff: The option -R fixes this...
Link to commentYou might want to fix this in your original script:
/usr/bin/svn diff $@|colordiff|less -R
Hope it helps!
Jakob on Mon, 16 Mar 2009 19:00:00 +0100
Thanks Lukas and Robin. I have incorporated both of your sugestions and bug fixes into the current script.
Link to commentgreetings
Jakob
Georg on Tue, 17 Mar 2009 15:31:21 +0100
very nice script, thanks - I'm using it since yesterday...
Link to commentLukas on Mon, 23 Mar 2009 16:25:40 +0100
It would also be great if it would pick the svn command from the PATH rather than hardcoding an absolute path to the svn command.
Link to commentJakob on Mon, 23 Mar 2009 22:14:32 +0100
Thanks for the hint. I changed the scripts accordingly.
Link to commentgreetings
Jakob
derek on Fri, 27 Mar 2009 13:27:25 +0100
I like the functionality added by this script, thanks!
Link to commentUnfortunately, it breaks a couple of things I like to be able to do, such as:
svn ci -m "This is my log message."
and
svn rm this/is/a/path/with\ a/space\ in\ it
Lukas on Wed, 01 Apr 2009 11:27:19 +0200
Not being a bash expert I am not sure whats going on, but with this stuff enabled I can no longer use the "svn copy" command. I always get the following error message:
Link to comment"svn: Local, non-commit operations do not take a log message or revision properties"
Jakob on Wed, 01 Apr 2009 23:53:52 +0200
@derek, @Lukas:
Link to commentI have updated both versions of the script, which should hopefully fix both of your problems :)
greetings
Jakob
Lukas on Thu, 02 Apr 2009 10:25:41 +0200
Thx .. but it seems like there is some encoding issue now? I tried to fix all the ^[ by hand, but it still does not seem to work anymore (using svn diff, just gets me the normal svn diff).
Link to commentJakob on Sun, 05 Apr 2009 00:58:52 +0200
I just checked the files. Everything works fine here on my side with the files linked in the blog entry.
Link to commentThe diff is done by colordiff. There are no escapesequences involved in the diffing example. At least not in the shell script ;). Manual colorcodes are only used for svn up and svn log.
Maybe your less is configured to disallow colors?
If you copied the contents of the file into your bashrc file, try to just add the line "source /path/to/svn/bashrc.txt" instead of the copied content. This way you can be sure the escapesequences haven't been messed up by your editor :)
greetings,
Jakob