SVN to Git
How to cleanly migrate from svn to git.
Git’s in, SVN’s out
Let’s face it, it’s 2010 and DVCS’s are in style. SVN and CVS are out, git and hg are in. All the cool kids (python & Ruby-istas alike) are jumping ship on SVN and git is the new cool tool.
So how do you jump on the bandwagon and kick your SVN habit to the curb?
How do you migrate from SVN to Git?
If you’re seriously considering a move from Subversion to a DVCS (and git in particular), please choose from the following options:
- You’re sick of subversion and have heard of git, but have no clue where to start
- You’re sick of SVN, but your team/job/friends are forcing you to stick with SVN
- You’re ready to move to git and leave SVN behind, but you need to port legacy code/repositories on your local server
- You’re ready to move to git and don’t have a place to host the code, or don’t care if it’s hosted in the cloud
- You think git is confusing and wish this article was about mercurial (hg)
If you answered #1 or #4, stop reading now and go over to Github and sign up for a free (or paid) account. Github will guide you every single step of the way, from setting up SSH keys to common git commands and gotchas. Not to mention the interface is very usable and downright helpful in many cases.
If you answered #2 (sick of SVN but stuck with it), you probably want git-svn to help bridge the gap. The ‘net is full of examples, tutorials, and quite frankly I’ve never had the patience to make it work right… but some people swear by it.
My biggest issue with using git-svn is you get some of the benefit of git (local commits, fast log access, etc) but none of the workflow changes that git inspires/prompts. Go read about the Integrator Workflow chapter on Pro Git. It looks like a lot of overhead to begin with, but it saves you SO much time in the long run, it actually improves code quality.
If you answered #5 (you don’t like git) — well, sorry, I haven’t used hg much. Best of luck, let me know how it works for you.
For the rest of you — those who are ready to migrate to git but don’t know how — read on!
First things first: install git.
If you’re on Linux, you need to install the “git-core” package — assuming you’re on Debian or Ubuntu, try
$ sudo apt-get install git-core
If you’re unlucky and stuck on RHEL, CentOS, or Fedora — first of all, I’m sorry that you have to deal with yum. Cross your fingers, and try
$ sudo yum install git-core
If the mirrors aren’t down and the planets align correctly, yum will eventually install git.
Export your SVN repository to Git
There are at least two popular ways to import from SVN to git. You can use git-svn (git svn clone -s SVN_URL LOCAL_DIR), but I haven’t had a lot of luck getting this to work right. Last I checked it leaves some annoying metadata and requires some extra hackery.
$ mkdir my_local_dir && cd my_local_dir $ svn2git http://my.svn.server/path/to/repo/and/subdir
That’s pretty much it, after svn2git runs you will have all of branches/tags/trunk imported into your local directory as a git repository. You may have to fiddle around with the options, and if you’re behind a proxy (why do corporations think this is useful or somehow more secure?!!! proxies cause SO many issues… sigh) then you may have to fiddle with $http_proxy.
Oh, and before I forget, you’ll probably want to create a “git authors” file — this provides a mapping between subversion-style user IDs (like abaker) and git-style IDs (Adam Baker <firstname.lastname@example.org>). This isn’t important for a dry run, but when you do migrate your code in the end, you’ll definitely want this to be working correctly.
Sharing your changes
Last but not least, chances are you’ll want to push all these commits to a bare repository on a central server somewhere. Git doesn’t require you to have a “trunk” or official repository, but most people generally designate one repository as the official / blessed / trunk repo. It just makes logical sense to have one spot where are the good code is, where everything’s clean/tested/reviewed and thereby ‘blessed’.
my_local_dir is on your personal dev box — I would highly recommend following something similar to the Integrator Workflow, in which case you’ll do the following
# initialize the bare repository which will be considered 'pristine' or 'blessed' (aka SVN trunk) [user@main_server:/path/to/repo] $ git init --bare # add the bare repository as a 'remote' (something you can push changes to) [user@dev_box:/path/to/my_local_dir] $ git remote add origin user@main_server:/path/to/repo [user@dev_box:/path/to/my_local_dir] $ git push --all
At this point, you've imported from your Subversion repository into a local git repo, initialized a 'blessed' (trunk) on your main server (which presumably everyone has SSH access to - or you've set up Gitorious, Github:FI, or gitweb) and you're ready to start coding!
If you've made it this far, you're definitely going to want to read the Pro Git book. Consider it the complete reference on git, and an invaluable asset on your way to becoming a git master.
The short answer is someone new to your team/project/etc will clone the blessed repository one or more times, make some local changes, commit them locally. Later, someone will pull those changes into the main repository when they're stable/reviewed/tested and otherwise considered ready for merging.
Git is a very powerful but often confusing DVCS. If you're new to git, I highly recommend you start with Github or Gitorious. They both provide a nice interface with tips and hints to help you with common workflow tasks, and they provide/require/strongly promote changeset review on every merge. It feels awkward at first, but it changes your life... seriously.
So what're you waiting for? Go 'git' started! (ha ha ha)