Thursday, December 6, 2012

Sync SVN Repository to a Bitbucket Git Repository

At my current job we have multiple Subversion repositories that are hosted internally with VisualSVN Server. This has worked great for us for many years now. Before subversion (and many many years ago) we used CVS as our version control tool and WinCVS for our client.

Well just as it was previously obvious that we needed to switch from CVS to Subversion, I'm starting to get a similar feeling with switching from Subversion to Git. So we are now interested in the possibilities of hosting private repositories in Bitbucket. We aren't experts in the GIT ecosystem and we run windows throughout here. Because of this I want to start with baby steps. I figured a good start would be to just get one of our internal repositories out into Bitbucket so the following are the steps I took (minus the many hours) to do just that.

Notice: I'm assuming there are many ways to do what I was trying to do. This is just the way I did it :) Also, these steps are unfortunately not complete. I did not record everything that I did here. I just had some notes after my success and thought I would share.

Step 1- Install Git for Windows

This project provides a fork of Git on Windows. I actually installed this months ago so I can't remember any specific issues that I may have had.

Step 2- Install Ruby

I can't remember if Git for Windows installs Ruby already for you or not. It probably doesn't but then I'm just not sure as I installed Ruby separately years ago but for some reason think that maybe Git for Windows has a dependency on it. Like I said though, it probably doesn't. None the less, Ruby must be installed.

Step 3- Install the Ruby gem svn2git

gem install svn2git

That should do it. I looked into other tools that supposedly migrated Subversion repositories to Git but this one seemed the best for me.

I tried several times to get svn2git to work but just couldn't. Then I realized that git already has git-svn built into it so I should just use that! At this point I'm not even sure that we needed Ruby installed. Like I stated earlier, these steps aren't compete.

Step 4- Clone the SVN Repository using git svn

Start up Git bash and type:

git svn clone -s https://server.local/svn/someProject

This clones the SVN repository (including the trunk, tags, and branches) into the directory you are in. The -s flag states that the repo structure is in the standard format. Be warned that if you are cloning an old/active repository that this will take a long time to complete. I actually recommend doing this once and then making a copy of the resulting folder. This way if you end up messing up something in the clone (like I did several times) you can just delete it and use the copy you created instead of having to run this command again.
Note: If you have a repository that you just can't do a complete clone of because it is too big you can run the following command:

git svn clone -s -r HEAD https://server.local/svn/someBigProject

The -r HEAD means to just grab the most recent version of the trunk so this will not include any history. If you do this then you can skip Step 5 below.

Step 5- Execute a Git Checkout

git checkout -b trunk remotes/trunk

This is needed because if you look at the folder that was created from the clone, you'll notice it is empty except for a .git folder. This command is checking out the trunk to the working tree. After this you'll see all of the code that was in your trunk.

Step 6- Change name of branch from trunk to master

git branch -m master

I don't think I had to do this but I thought it was a good idea as master seems to be the convention for Git.

Step 7- Update the Working Tree

git svn rebase

The documentation states that this fetches revisions from SVN and "rebases" the current tree and that it is similar to an svn update. The thing is though is that when I did this I expected nothing really to happen because I just pulled from svn and there weren't any commits to it but for some reason this acted like it was doing a bunch of modifications.
Now things get even weirder. I ran the same command again:

git svn rebase

This seemed to do even more updates and took a little bit of time to complete. At this point when I ran the same command again I received the following response:

'Current branch trunk is up to date.'

That's what I was expecting the first time I ran that command. I don't understand but this is what worked for me.

Step 8- Create a New Bitbucket Repository

I created a private repository.

Step 9- Generate & Install SSH Keys

I would assume that you can following this documentation to do this. I used it to install the keys that I created but I didn't use PuTTygen to generate them. Instead I used ssh-keygen. I basically followed this Github documentation except for step 4. A good way to test that you have the keys set up properly is to execute the following command:

ssh -T

If you receive a message similar to the following then you are good to go:

conq: logged in as gbrunton.
You can use git or hg to connect to Bitbucket. Shell access is disabled.

Step 10- Prepare repository for Bitbucket

git remote add origin ssh://

This adds a remote for the repository. Whatever that means :) I noticed though that it updates the config file within the .git folder.

Step 11- Push to Bitbucket

git push -u origin master

This command pushes the local repo into Bitbucket with all of the trunk master history!

Step 12- Schedule Daily Task

Because all I want right now is to just copy what gets committed into SVN over to Bitbucket, I created a batch file that gets ran by the scheduler.


This took quite a bit of time to figure out and really isn't that useful as is. In order to completely remove our SVN usage we would have to be able to migrate our Bugzilla bugs over to Bitbucket's Issues. We would also have to find a replacement for the current commit hook we have between SVN and Bugzilla. At this point I think this was a good first step.

Helpful Links

No comments:

Post a Comment