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 <firstname.lastname@example.org>
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!