Convert SVN Repo to Multiple Git Repositories, the Simple Way

I was faced with a (pretty common) scenario recently: I had been using one giant SVN repository for all of my various projects, and I realized it was time to step into the 21st century and get those projects into separate git repositories. I’ll admit, I was originally hesitant to use git; I thought SVN would be all I ever needed. However, I had to learn it due to my work with Drupal, and after a bit of forced exposure I realized just how nice it was to have the entire repository right there on my computer.

I did a lot of research, and tried a bunch of different ways to convert an SVN repository to multiple git repositories. Here’s what I came up with as the easiest way (this tutorial assumes you have git installed and are familiar with the command line). Note that if your SVN has gone through any major re-organizations, this probably won’t preserve the full history, and you’re probably off trying something more complicated. This process also works best with simple SVN setups that don’t have branches (but should work with branches as well).

Step 1: Setup authors-transform.txt
In order to translate the SVN usernames to meaningful git commit/author name+email addresses, we will make a text file that maps the former to the latter. If it’s a personal repo, you probably know the few usernames that had access, and can thus create the file from memory. If not, you might want to use a script to grab all users from the repo. Either way, you want a text file that looks like this:

[old SVN username] = [New Name] <[new@email.com]>

an example:

Tommy = Tommy Goode 
Scott = Scott Mann 

Step 2: Clone a project from the SVN repository into git
This step will be repeated once for each sub-project in the repo. Get yourself into an empty (except for authors-transform.txt) folder and run the following command:
[crayon lang=”sh”]git svn clone [base svn url] –no-metadata -A authors-transform.txt –trunk=[relative/path/to/project/trunk][/crayon]
If you have branches, add --branches=[relative/path/to/project/branches]. Git will do it’s thing, and then BOOM, you have a git repo with all of your SVN commits. Do a simple [crayon lang=”bash”]git branch -rd trunk[/crayon] to get rid of the remote branch reference. You may also want to pack the repo, since as a brand new git repository it has not yet been optimized. [crayon lang=”bash”]git repack -d[/crayon]

Hooray! No more SVN. If you want to push it to a remote repo, just do a
[crayon lang=”bash”]git remote add origin [remote url]
git push -u[/crayon]

Use SVN 1.7 in XCode 4.3+

tl;dr: Skip to the good part!

A while back, Subversion 1.7 was released. It was a major upgrade, and included an entirely new way of internally keeping track of local working copies. Unfortunately, the svn tools in XCode 4 are not compatible with the new format, and thus could not read the status of (or commit) code on the server.

Luckily, someone figured out a way to ‘patch’ Apple’s default SVN files with the new version. I first saw this on StackOverflow, and used it successfully for a few months waiting patiently for XCode to be updated.

Soon enough, there was a new version of XCode! And it was available through the Mac AppStore! And I had to spend a ridiculous amount of time working on my Hackintosh to get it upgraded to 10.7.3 so I could use the new version! …But that’s a story for another time.

After installing 10.7.3 and downloading XCode 4.3.1 from the Mac AppStore, I started it and immediately went to the repositories section, expecting to see my working copies listed and ready to be updated and committed. Unfortunately, what I got instead was a bunch of errors and “Cannot connect to repository” messages. I realized that the AppStore verson of XCode included it’s own copies of the SVN binaries, and wasn’t even using the ones that I had patched earlier. After looking a bit further, I realized that the new version of XCode had the SVN binaries packaged inside XCode.app. So how could those be updated to the new version?

The Good Part (AKA How To Upgrade to SVN 1.7 in XCode 4.3.x)

The good news is, upgrading SVN inside the XCode.app package isn’t too different from upgrading the old way.

This assumes you already have SVN 1.7 installed to /opt/subversion. You can get it from WANdisco (scroll down to the Vanilla Subversion section).

First, open Terminal and get an elevated shell using {shell}sudo -s{/shell} and typing in your password.
[shell]
tommylaptop:~ Tommy$ sudo -s
Password:
[/shell]

Then, cd to inside the XCode.app package, to where the SVN binaries are.
[shell]bash-3.2# cd /Applications/Xcode.app/Contents/Developer/usr/bin/[/shell]

Make a backup directory and move the old SVN files into it
[shell]
bash-3.2# mkdir bup
bash-3.2# mv svn* bup/
[/shell]

Lastly, symbolically link the new files into the package:
[shell]bash-3.2# ln -s /opt/subversion/bin/svn* ./[/shell]

That’s it! Note that this doesn’t seem to work 100% of the time (I still get random error messages sometimes), but it’s still nice to see the working copy status next to each file in the project, and be able to commit/revert from inside XCode. Also note that an update to XCode could break this – hopefully, by upgrading the SVN components *cough* – but the same procedure will probably work to restore SVN 1.7 functionality if the next update fails to deliver.