Migrating a Subversion Repository to Git

September 16th 2013 Git SVN

I've been using Git instead of Subversion for new projects for a while now, though I left many older ones still active in Subversion. During a recent hardware upgrade I decided not to install Subversion server again, but rather migrate the old projects to Git as well. This post describes the process I have come up with, just in case I ever need it again.

Since Git has built-in support for synchronizing its repository with Subversion, there is no other tool required for the migration. The first step clones the Subversion repository of the project into a new local Git repository. For starters let's ignore branches and tags, limiting ourselves to migrating only trunk:

git svn clone https://svn.domain.com/repo/folder/to/trunk LocalFolderName

This will pull all revisions from the given SVN repository folder into a new local Git repository inside the given folder. It could take a while for a large repository with many revisions. If you don't want to migrate all of the revisions you can pass a range of revision:

git svn clone https://svn.domain.com/repo/folder/to/trunk -r 123:HEAD LocalFoldername

This time all the revisions since the starting one will be migrated to the Git repository, reducing the final size of the repository and the duration of the migration accordingly. Just make sure your source folder was already created at the starting revision.

Now it's time to completely detach the new Git repository from the source Subversion repository, otherwise it will remain configured for synchronization with it. This requires manually deleting the following subfolders inside the .git folder of the new repository:

  • svn
  • refs\remotes file
  • logs\refs\remotes file

The last thing to delete is the following section in the .git\config file:

[svn-remote "svn"]
    url = https://svn.domain.com/repo/folder/to/trunk
    fetch = :refs/remotes/git-svn

To push the repository to a remote location a new remote needs to be created with an upstream branch (run the command from the root of the local repository folder):

git remote set-url origin https://damirarh@bitbucket.org/damirarh/RemoteRepository.git
git push --set-upstream origin master

And that's it; you're done. From this point on you can push and pull commits to and from the newly defined remote repository.

Unless you want to migrate your branches and tags as well, that is. Otherwise you'll first need to pull them from the SVN repository at the very beginning of the process:

git svn clone -s https://svn.domain.com/repo/folder/to/root LocalFolderName

Notice the use of –s argument which denotes a standard Subversion repository with trunk, branches and tags folders at the root level. Also make sure to pass the path to this root folder instead to the trunk and you'll successfully migrate all the tags and branches to the local Git repository.

Before detaching the Git repository from Subversion, local branches and tags corresponding to the remote SVN branches need to be created. Start by listing all of them:

git branch -a -v

Output should look similar to this:

* master            d78caeb Description
  remotes/branch1   acf2ea6 Description
  remotes/branch2   537d53a Description
  remotes/tags/tag1 435c87f Description
  remotes/tags/tag2 b34d251 Description
  remotes/trunk     d78caeb Description

For each of the remote branches a local branch can be created as follows:

git branch branch1 acf2ea6

For each of the remote tags a local tag can be created as follows:

git tag -a tag1 435c87f -m 'Message'

Now it's time to follow the rest of instructions:

  • Detach the repository from SVN by deleting the previously listed folders and the config section. The latter has two additional lines; delete them as well.
  • Create the remote and push the master branch to it.

To push the branches to the remote repository as well, use the following two commands for each one of them:

git checkout branch1
git push -u origin branch1

To push all of the tags to the remote, only a single command can be executed:

git push --tags

By following the above procedure you have migrated all of the information from Subversion to Git; feel free to delete the original Subversion repository now.

Copyright
Creative Commons License