How to Migrate from SVN to Git

You’re still using SVN!?

Jim Blandy trembles as he watches Linus tempt you to come closer. Linus throws his VCS at you with horrible puns such as: ‘Git closer my boy’ and ‘In Git We Trust’.  He appears angelic while you are wondering why Jim ever captivated you in the first place.  Maybe it was the SVN charm?

You start forgetting the SVN commands. Worse, you start confusing Git commands with SVN when talking to friends. No longer will you be the only person answering yes to, “Does anyone use SVN?”. As soon you are done migrating to Git you will be denouncing SVN. You are starting to smile now and begin to think of ways to act like you’ve always ‘Gitted’ before.  SVN? What is that!?

Your smirk drops.

It dawns on you that you have to migrate your code repositories first and you have no idea on how to start.

SVN to Git

I was tasked with migrating our SVN repositories to Git. Originally the idea was to cut ties and loose the history. We decided it is important to maintain history if possible.  The first step was identifying our repositories and our svn-externals in the repositories.

First up was gathering the SVN authors.  Your mileage may vary and you might find a more useful command but in general you need the svn author’s to map to Git authors.  I recommend using a public email address for the Git author just so it is easier when looking at history – especially if using a hosted solution.

Second, I cloned did a ‘git svn’ clone on our main product’s repo.  This command was done on the repo itself and not trunk or a branch.  This is needed to maintain all the history if you choose to do so.

Next, it is time to clean the repo.  Technically it should only be done in ‘edge’ cases and for our case – we needed it because we wanted a clean break.  After this you can perform git branch or git tag and see the old svn branches and tags. Pay special attention to the “Clean the new Git repository” part!

Now the fun! Set your remote up with `git remote add origin <github|bitbucket|gitlab>` and try a `git push origin –all`.  Did it work!? Did it push everything! It did in my case – and now we are one step closer.

What about those pesky svn:externals?

There is no way, that I know of, to convert svn:externals to a git submodule or something else by hand.  We decided on using Composer for many reasons.  The main points are: easier to manage semantic versions of dependencies, large user base, open source, and our internal dependencies already leveraged Composer.

I had to convert them over by hand.  It wasn’t really hard at all though since our svn:externals file pointed the dependencies to /vendor anyway.

What is next?

Right now I am working on the build process to get PHING to use Git.  Shouldn’t be too hard.  The longest part of this process is waiting for the five plus years of code to download from SVN.  The next challenge was getting the repositories prepped and fixed so we didn’t have failing tests.  I’ll save that for another post.

What do you think?

I’d be interested to hear your feedback in the comments below! Has your conversion been a nightmare or a dream? What struggles did you have? Thanks!

Quick references I found useful:

  • Why’d you make it sound easier than I’ve been making it out to be? It’s great to see Git getting into it there. You left and we were still complaining about it, you went back just in time to finish tipping it! I will actually be converting a massive svn repo into about 20 smaller git repos. My primary problem has been the fact that I’ve been using svn-load for years to maintain vendor branches in svn. Using vendor branching in git means I have split the repo

    Composer solves some problems but it also introduces a few more, that now you are blindly assuming that the repositories will never be compromised. Not something I’d go for at the enterprise level to be honest. I wonder if satis and pulling the release packages into that would work, this would effectively be creating your own packagist repo.

    • Gitting it done! I’d be interested to read about your experiences for converting the svn repo into 20 smaller git repos. I think it was easiest at LPi due to the fact that the svn workflow is trunk is stable, branches are features, bug-fixes are applied to trunk. So the only reason it was easy is because of the way it was setup in the past and maintained over the years :).

      Thanks @David and @Aaron!