April 19, 2009

I hate SVN, or: here’s a tool I use to make diffs better

Filed under: General Information — Ryan Wilcox @ 9:33 am

The Intro, and the frustration

So SVN’s command line interface could be a lot better. Specifically, svn diff.

Use case: I update and see a change someone else has made. I want to see what modifications they made relative to what it used to be… how do I do this?

The answer using the straight svn command line is so:

  1. Figure out what revision the file changed under (mindful that the revision subversion reported to you when you did an update may actually not be the revision of the last change, if you have multiple projects in the same repository and some other part of the revision changed between this change and the HEAD of the repository).
  2. Figure out what the revision-before-that-was. If you’ve figured out #1 by doing an svn log, well you have this number too.
  3. svn diff -r revision-from-step-2:revision-from-step-1 somefile

Which sucks. For one it’s too many steps, and then there’s general svn unhelpfulness.

To make your life more ‘wonderful’, svn diff will return nothing in the following situations:

  1. The file has not changed between the revisions you specified. (Obviously you didn’t do steps #1 and #2, but svn is not going to tell you this)
  2. The file doesn’t exist in the repository at all. (Obviously you screwed up the file name, but svn is again going to remain silent).

So if svn returns nothing you have one of these two things going on. Good luck debugging, buddy.

But yes, the suck. Non obvious, and WAY to much work if I just want to see what changes some coworker made to my codebase. This needs to be a fast step: I just want to do a code review quickly and get back to work!!!

A tool to make it better

So I wrote a tool to make it better. Granted, an inefficient shell script to make it better, but hey.

This shell script accomplishes two thing:

  • Gets rid of having to do steps #1 and #2. Instead you give the shell script what i call a revision offset. (“Compare the current version to the version one change ago”). This is NOT revision number — remember that there may have been other changes since that file changed… but “revision offset” is a relative number — “N changes ago”.

    Sadly, not in English like that, but it’s a bash script — maybe I’ll rewrite it someday and use Python and PythonMethodMatcher.

  • HELPS you debug. “Hey, buddy, I think that file doesn’t exist. You sure about that?”
  • This tool will also helpfully tell you what it’s doing, so it’s not opaque magic — if you want to do something different you can take what the script generates, modify it and off you go. This tool is transparent and wants to help you.

The shell script is far from perfect (it’s pretty inefficient, because I’m not a master bash coder), but it does make this less frustrating.

Example Use Case

$ ls
README.txt somefile.sh someotherfile.sh
$ svn log README.txt
------------------------------------------------------------------------
# r170 | someone | 2009-04-09 22:52:59 -0400 (Thu, 09 Apr 2009) | 1 line
#
# a change
#------------------------------------------------------------------------
# r167 | someone | 2009-04-06 09:43:25 -0400 (Mon, 06 Apr 2009) | 1 line
#
# another change
#
....

# ok, enough background for the reader, on with the show!

$ svndiffrelative 0 1 README # <-- "compare the current revision to 1 change ago" file README does not exist. CHECK THE NAME! Use --force to if you want to do this on a deleted file $ svndiffrelative 0 1 README.txt comparing revision: 170 to 167 running: svn diff -r 167:170 README.txt Index: README.txt =================================================================== --- README.txt (revision 167) +++ README.txt (revision 170) @@ -125,6 +125,8 @@ + hello world!

The Script

Download the script from my site!