Subversion pre-commit hook for Redmine

Close on the heels of my last post, here’s a little pre-commit script to help integrate Redmine issues with svn commits. The basic idea is that you can’t commit code to the repository without referencing a Redmine ticket. I searched the tubez for quite a while looking for something else like this. I found this forum post, but it had a bunch of shell syntax that didn’t work for me on Dreamhost.

I hereby disclaim that this was a quick hack for me and understand that there is probably a better way to do this. If, however, you’re not passionate about this sort of thing and just want something that works, it’ll do.

I’ve actually got 2 scripts for ya:
The SVN Hook
Copy and paste this first one into a file named ‘pre-commit’ (no file extension), and drop it into the hooks directory of your svn installation. This script will be called automatically by svn whenever someone tries to commit. All it really does is pass the submitted comment string on to our ruby script, featured below.




# change to the current working directory
cd `dirname $0`

# svnlook at the comments being submitted with the commit request

# Holla out to a little ruby pre-commit script.  if it fails, exit with a return
#    code of 1, which means that errors occurred
/usr/bin/env ruby pre-commit.rb "$COMMENTS" || exit 1

A Ruby pre-commit script (pre-commit.rb)
Copy the following code and paste it into a file named ‘pre-commit.rb’. Drop the file into your svn/hooks directory alongside the pre-commit script created above.

#!/usr/bin/env ruby

comments = ARGV[0]

if /[a-zA-Z0-9]/ !~ comments
  raise "You must include a comment with your commit."

if /refs|fixes|closes\s#([0-9]+)/ !~ comments
  raise "You must reference a Redmine issue in your commit comments (e.g. 'refs #1234')."

issue_number = comments[/#([0-9]+)/][/([0-9]+)/]

# Change the username, password, hostname, and dbname in the following line
#    to match your settings
command_line_output = `/usr/bin/mysql -N -u your_mysql_username -pyour_password \
    -h your_redmine_dbname -e \
    "SELECT COUNT(*) FROM issues I INNER JOIN issue_statuses S \
    ON = I.status_id WHERE S.is_closed = 0 AND = #{issue_number};"`

redmine_issue_open = command_line_output[0,1]
if '0' == redmine_issue_open
  raise "Issue ##{issue_number} is not in an open state."

Whew! That’s 2 techie posts in a row! I’ll try to come up with something more fun for everyone next time.

This entry was posted in Software Development and tagged , , , , .
Bookmark the permalink.
Follow any comments here with the RSS feed for this post.
Both comments and trackbacks are currently closed.


  1. Posted August 11, 2008 at 8:35 am | Permalink

    Note: I can’t get ‘\’ characters to show up inside tags, so you should know that the line in the ruby script above that begins with “command_line_output” and continues with the next 3 indented lines should have ‘\’ chars at the end of each line so that the ruby interpreter interprets that statement all as one line.

  2. Dave S.
    Posted August 19, 2008 at 5:24 pm | Permalink


    Dude you are a techie! That rules!

    Have you found ruby to be worth getting into? I’ve generally been using Python for most lightweight scripting duties – I prefer C for most stuff I want to actually do.

    Does Ruby offer an advantage for non-web-based scripting?

    Also, I’ll have to look into this Redmine stuff – does it actually increase your productivity for technical projects?

  3. Posted August 22, 2008 at 9:38 am | Permalink

    Hey Dave!

    I like Ruby a lot. It’s really pretty similar to Python and there’s not much reason to switch if you’re already used to Py. Without trying to start a flame war (yeah right, like there are enough people reading this blog for that), the big problem with Python for me is significant white space. I worked on a Python project with a guy a while back who would not stop using crappy editors that messed up the whitespace and broke the code constantly…that pretty much eliminated my desire to use it when I had a choice. A lot of the reason I like Ruby is because I like Rails, but Ruby stands on its own as a pretty great scripting language.

    Yeah, Redmine rocks…Trac does a lot of the same stuff, though, and it’s written in Python, so it’d be easier for you to write plugins if you wanted. My main reason for switching was ease of setup and multiple project support. They’re both great, though, because you get wiki, ticketing, project management reporting, source code repository browsing, and lots of other goodies all in a one-stop shop. The things I like best about it are the Activity (called Timeline in Trac) page which provides an RSS feed of all changes that anyone makes to the tickets, wiki, source code, etc. and being able to link source code checkins to open tickets.

    Great to hear from you! Take it easy.

  4. Dave S.
    Posted August 22, 2008 at 3:18 pm | Permalink

    Thanks for the info Sam, I’ll definately import this stuff into my intranet to check it out.

    I’m out in MD now, and I’m married (no kids yet). I live in a townhouse in Odenton, between Washington and Baltimore and Annapolis.

  5. Sarah
    Posted September 20, 2008 at 7:17 pm | Permalink

    huh???? (and I mean that with sincere respect and awe).

  6. Posted October 3, 2008 at 12:28 pm | Permalink

    Totally forgot that you posted this. Went to the web to see if this was a Redmine default or option and your post on this was the first search result.

    I’m going to hand these to our hosting people and see if they can get it to work.


  7. Kelvin
    Posted January 13, 2009 at 3:11 am | Permalink


    I install subversion & redmine on a windows server.
    The hook scripts can’t work, I should be how to do that the hooks could run.

One Trackback

  1. […] to Sam and the post, the transition was […]

librarian, writer/editor, floundering guitarist, breakfast addict

mobile software developer, dog owner, hiker, adventure racer, enemy of bureaucracy
Follow sam2themax on Twitter Subscribe to this blog