Migrating multi-project Subversion repositories to Git

So I finally gave in and submitted to the version control Gods, Git is the way to go. Of course it would happen that Git repositories are typically a single-project-per-repo situation, and I have a couple globbed together Subversion repositories with many projects in them. How do I separate out my histories from the individual projects, maintain tags and branches, and not lose that precious history that nobody really ever looks at anyway?

Well, luckily there is a nifty script called svn2git that gets us the bulk work of migrating history of a single Subversion repo to a new Git repo. Coupled with a few admin tools that come with Subversion, we got it covered.

The current situation

I have a couple repositories, looking like the following:

/var/lib/svn/repo1
  /project1
    /trunk
    /tags
    /branches
  /project2
    /trunk
    /tags
    /branches
/var/lib/svn/repo2
  /project3
    /trunk
    /tags
    /branches
  /project4
    /trunk
    /tags
    /branches

The desired situation

I’d like them all separated, with all history!!! Resulting in the following structure:

/var/lib/git/project1.git
/var/lib/git/project2.git
/var/lib/git/project3.git
/var/lib/git/project4.git

Step 1 – Dump your projects from the Subversion repository

Subversion ships with a tool, svnadmin, that will help dump a repository. It must operate on the local filesystem of the Subversion repository, not a working copy. As a result, it only dumps full repositories, hence the problem in general.

Be not afraid though! Subversion also ships with svndumpfilter, the key to our salvation.

For my example above, to dump project1, project2, project3 and project4 into separated Subversion repositories, I would:

$ mkdir svn-convert && cd svn-convert
$ svnadmin create project1.svn
$ svnadmin create project2.svn
$ svnadmin create project3.svn
$ svnadmin create project4.svn
$ svnadmin dump /var/lib/svn/repo1 | svndumpfilter include project1 | svnadmin load project1.svn
$ svnadmin dump /var/lib/svn/repo1 | svndumpfilter include project2 | svnadmin load project2.svn
$ svnadmin dump /var/lib/svn/repo2 | svndumpfilter include project3 | svnadmin load project3.svn
$ svnadmin dump /var/lib/svn/repo2 | svndumpfilter include project4 | svnadmin load project4.svn

And viola, separated Subversion repositories.

Step 2 – Convert via svn2git

First, download and install svn2git, it’s a Ruby script, the instructions are good, it’ll work for you.

Next, create a text file, ‘authors.txt’ with contents like the following:

name1 = Full Name <email@example.com>
name2 = Another Name <email2@example.com>

Substituting the names of users who have committed to the Subversion repositories of course. This will map the Subversion users to Git authors.

Next, we make a place for the new repository and run the conversion utility. It will init the Git repository and create the necessary history.

$ mkdir project1.git && cd project1.git
$ svn2git file:///home/nick/svn-convert/project1.svn \
    --trunk project1/trunk --branches project1/branches \
    --tags project1/tags --authors ../authors.txt

Repeated for each repository with appropriate substitutions, and you’ve got yourself some Git repositories.

Quick verification should show you you’re in business:

$ git tag
v1.0
v1.0.1
v1.0.2
v1.0.3

$ git branch
* master
  ticket102
  ticket87

All that is left is to put them in a safe place and start cloning!