Third Helix is now Kickbomb Entertainment! Please visit kickbomb.us for all future updates.


08 Sep 2013

SourceTree is an excellent, free, GUI-based client for Git and Mercurial. I’ve talked about it previously in Using External Version Control With Unity, and I’ve used it extensively since then for Mercurial-based Unity project source control in both solo and team environments.

In my opinion, Mercurial is the hands-down the best version control system for Unity projects. However, everyone has their own preferences, and I’ve recently started working with another developer who’s using Subversion. There are some decent GUI-based Subversion clients for Mac out there (Cornerstone particularly stands out) but there were a few things bugging me about these choices:

  • Committing changes always means uploading them to the server, which is slow. This is a big reason I love Mercurial: I can commit locally as I work (this is very fast), and then push a bunch of commits to the server all at once (e.g. at the end of the day, when it’s okay for this to take a few minutes).
  • They’re all paid products. They’re reasonably-priced, but Subversion itself is free, so… yeah.

What I really wanted was a way to work locally (and quickly) using SourceTree and a Mercurial repository, and then at the end of the day push the changes from local Mercurial to the remote SVN server.

As it turns out, SourceTree actually supports this, using a plugin called hgsubversion which effectively sets up a bridge between Mercurial and SVN. According to the SourceTree documentation, this functionality is already built in: all you need to do is clone a new repository and provide the URL of an SVN server, and it will automatically detect that it’s an SVN repository and set everything up for you.

It sounds so simple, but in practice, it turned out to be an enormous pain in the ass. The SourceTree documentation on this point is woefully inadequate to the point of being actively misleading, and what little information exists in Atlassian’s online knowledgebase outright omits critical details that, unless you’re a Python guru, you’d never have any way of knowing.

After several days of digging through all this confusion, I did finally get SourceTree connected to our SVN repository. And since there appear to be no straightforward instructions about this anywhere on the Internet, here’s my step-by-step guide to the problems I encountered, and how to make this thing work.

For reference: I’m running SourceTree on Mac OS X 10.8.4. I have no idea if or how these problems might manifest under Windows. I already had Python 2.7 installed; I’m not sure what kind of error(s) you’d run into if it wasn’t, but you may want to get that squared away first if it isn’t already.

Problem #1: SourceTree Doesn’t Auto-Detect SVN

The SourceTree documentation says this:

SourceTree cannot use an existing Subversion checkout, because that doesn't contain enough information to construct a full repository. Instead, you will need to clone from the Subversion server - and you do this in exactly the same way as you clone a Mercural or Git repository from a remote location; just drag & drop a Subversion server URL into your bookmarks window, or click 'Add Repository' and fill in the Subversion URL in the Clone tab. SourceTree will automatically detect that it's a Subversion repository, and give you the option of creating a Mercurial or Git repository locally from it.

Pretty straightforward, right? And yet when I did this, SourceTree returned an error that “this is not an hg repository”. Clearly SourceTree is not auto-detecting SVN.

The problem here is that Subversion itself is not installed. You’d think SourceTree would embed this, just like it embeds Git and Mercurial… but no. And the docs don’t mention this dependency, so good luck figuring it out.

The simplest solution is equally counterintuitive. It turns out that Xcode bundles Subversion, but doesn’t install it by default… brilliant. So you’ll need to do it manually:

  1. Install Xcode from the App Store if it’s not already installed (it’s free, but it will take a while)
  2. Run Xcode and go to Preferences -> Downloads
  3. Under the Components tab, locate the Command Line Tools entry and click Install
  4. When the install completes (which may take an absurd amount of time), quit Xcode and restart SourceTree

After installing the Xcode Command Line Tools, restarting SourceTree, and pasting in an SVN URL, SourceTree correctly recognized it as an SVN server.

Problem #2: No Compatible Bindings Available

Now that my SVN repository was correctly recognized, I went ahead and cloned it. SourceTree immediately threw back an error:

abort: no compatible bindings available:

Subversion 1.5.0 or later required, but no bindings were found

Subvertpy 0.7.4 or later required, but not found

Please install either Subvertpy or the Subversion Python SWIG bindings!

There’s an Atlassian knowledgebase article that attempts to address this very problem. It suggests running the following commands in Terminal to install and configure the missing bindings:

  1. ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
  2. brew install --python subversion
  3. sudo sh -c 'echo /usr/local/lib/svn-python > /Library/Python/2.7/site-packages/subversion.pth'

These steps install Homebrew, a Mac package manager, and then use Homebrew to install and setup the required bindings. (Isn’t nix just *delightful?)

So I ran these steps, which for all their cryptic command line nonsense actually went off without a hitch. That is, until I tried again to clone our SVN repository.

Problem #3: Incorrect PATH Order

I still got the same error in SourceTree as before

abort: no compatible bindings available:

Subversion 1.5.0 or later required, but no bindings were found

Subvertpy 0.7.4 or later required, but not found

Please install either Subvertpy or the Subversion Python SWIG bindings!

…so I had to dig further.

At the end of Homebrew install process it recommends running the command “brew doctor” (which, let’s be honest, sounds fucking awesome). This spewed a number of warnings, one of which was particularly suspicious:

Warning: /usr/bin occurs before /usr/local/bin

This means that system-provided programs will be used instead of those

provided by Homebrew. The following tools exist at both paths:








Consider setting your PATH so that /usr/local/bin

occurs before /usr/bin. Here is a one-liner:

echo export PATH="/usr/local/bin:$PATH" >> ~/.bash_profile

This one was mercifully easy, since it tells you right there what to do (if only the rest of *nix could take such an approach…) So I executed the Terminal command to fix my PATH:

echo export PATH="/usr/local/bin:$PATH" >> ~/.bash_profile

And after that, for good measure, I logged off and logged back on. I’m not certain if this was necessary, but… yeah.

Problem #4: Still No Compatible Bindings Available

Having apparently installed the required bindings and set the correct PATH to locate them, I tried again to clone the SVN repository, and got the same error back yet again:

abort: no compatible bindings available:

Subversion 1.5.0 or later required, but no bindings were found

Subvertpy 0.7.4 or later required, but not found

Please install either Subvertpy or the Subversion Python SWIG bindings!

I’ll be honest, I almost gave up at this point. To keep hitting the same brick wall over and over after days of fruitless research is just powerfully demoralizing. But I hate to get my ass kicked by silly problems like this, so I soldiered on and started reverse-engineering what in the almighty hell SourceTree is actually trying to do here. That is to say, where are you trying to find these bindings? And what is this mysterious subvertpy, anyway?

Well it turns out subvertpy kind of is the bindings, and just nobody thought that was an important detail to maybe mention. Cool.

So next we need to go get and install that:

  1. Download package from https://pypi.python.org/pypi/subvertpy
  2. Unzip, navigate to that folder in Terminal
  3. Run command: “python setup.py build” (no quotes)
  4. Run command: “sudo python setup.py install” (no quotes)

At one point I had been rooting around in /usr/local/ looking for the svn-python package we supposedly hooked up back in our previous round of Terminal silliness, and it was nowhere to be found. I thought that was awfully suspicious, and hoped that subvertpy might be the solution. It wasn’t, but as it turns out, that also apparently doesn’t matter… because *nix makes sense, and all that.

Anyway, subvertpy was installed, so it was time to restart SourceTree.

Problem #5: This Is Actually Terrible

Finally, after all that nonsense, SourceTree was able to clone the SVN repository to a local Mercurial repository without issue. I danced a little jig, and then started writing this article to hopefully guide others through these dark woods of madness. As I finished the draft, it occurred to me that I’d better test actually making and committing some changes.

I really shouldn’t have done that.

I ended up with three trivial changesets in my local Mercurial repository, ready to be pushed. So far, so good. When I pushed to the SVN server, SourceTree threw back this error:

Found a branch merge, this needs discussion and implementation.

Completed with errors, see above

There are no branches in my Mercurial history: it’s one straight stream of changes.

When I clicked OK, things got even stranger. Once the push dialog closed, that unbranched stream of changes suddenly showed as having been branched twice, with the second and third changes duplicated in two different branches each. Basically, a complete mess.

Digging further, it looks like (and I’m not 100% certain of this) that hgsubversion actually pushes multiple changes by:

  1. Pushing the first one to SVN
  2. Pulling the latest from SVN (thus getting the pushed change right back)
  3. Trying to rebase the newly-pulled changeset… and apparently shitting itself at that point?
  4. Whatever the failure in step 3, it leaves a bunch of open branches, and then tries to loop back to step 1.
  5. “Hey, what are these branches doing here? I don’t support branches!”

I surmise that this will all work as long as I push each change as I commit it, and never stack multiple un-pushed changesets. But that right there defeats my whole purpose for using Mercurial in the first place!

So I guess I’ll be buying Cornerstone and working in push-to-the-server-for-every-commit SVN land from now on (for this one project, anyway). If you have any better luck getting this to work, please let me know in the comments. The dream of working locally in Mercurial and being able to push those changes to a remote SVN repository is still a great one; I’d love to have something like this that actually functions!

Posted In: