Ruby Subversion Bindings

Subversion has bindings for a variety of languages: Java, Perl, Python and Ruby. Of these I am most interested in the Ruby bindings as I’m building a Rails application. Unfortunately the documentation is completely lacking and bits of it are scattered throughout the web. This is an attempt to provide the code and how-to for the most common tasks.

Before we get to the code, validate you have the Ruby Subversion bindings installed correctly by running irb from a terminal:

irb(main):001:0> require ‘svn/client’
=> true

Onto the source code. Start it off by including the required svn modules:

require "svn/core"
require "svn/client"
require "svn/wc"
require "svn/repos"

Then setup the context with your subversion credentials:

ctx = Svn::Client::Context.new()
ctx.add_simple_provider
ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = 'username'
ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_PASSWORD] = 'password'

Now you can run any of the following commands on a remote subversion repository.

SVN Info

repos_uri = 'http://svn.website.com/project/trunk'
revision = 50
begin
  ctx.info(repos_uri, revision) do |path, info|
    puts("Url: #{info.url}")
    puts("Last changed rev: #{info.last_changed_rev}")
    puts("Last changed author: #{info.last_changed_author}")
    puts("Last changed date: #{info.last_changed_date}")
    puts("Kind: #{info.kind}")
  end
rescue Svn::Error => e
  # catch a generic svn error
  raise "Failed to retrieve SVN info at revision " + revision.to_s
end

SVN Checkout

repos_uri = 'http://svn.website.com/project/trunk'
output_dir '/home/billy/project_name'
revision = 50
begin
  ctx.checkout(repos_uri, output_dir, revision.to_i, nil)
rescue Svn::Error::CLIENT_UNRELATED_RESOURCES => e # revision doesn't exist
  raise "No such revision " + revision.to_s + " at " + repos_uri
end

SVN Log

repos_uri = 'http://svn.website.com/project/trunk'
ctx.log(repos_uri, 0, 'HEAD', 0, true, nil) do |changed_paths, rev, author, date, message|
  puts("Revision: #{rev}")
  puts("Author: #{author}")
  puts("Date: #{date}")
  puts("Message: #{message}")
  puts("---------------------------")
end

SVN List

repos_uri = 'http://svn.website.com/project/trunk'
ctx.list(repos_uri, "HEAD") do |path, dirent, lock, abs_path|
  if !path.blank?
    puts("Path: #{path}")
  end
end

That should get you started with the ruby bindings. If you want to know how to do anything else let me know in the comments.