Migrating a Subversion repository to a remote Git repository
Migrating an existing SVN repository to git is pretty easy; here’s a quick step-by-step guide (and reminder to myself).
Before we start, let’s make sure git and git-svn are installed:
$ sudo apt-get install git git-core git-svn
1. Getting the code out of Subversion
First, use git-svn to get a copy of the remote Subversion repository you want to migrate. For instance:
$ git-svn clone --authors-file=git-svn-users.txt --stdlayout https://my.svn.repository.com/MyProject
A couple of words on these options:
- clone gets a copy of the entire repository, including all commit history, tags and branches
- –stdlayout tells git-svn that you have laid your SVN repository as per the SVN recommendations, namely with top-level folders for trunk, tags and branches. If not, you can specify the paths for these relative to the repository root using the –trunk, –tags and –branches switches respectively (instead of –stdlayout)
- the –authors-file option allows you to map SVN users to git users, for the commit history; the file should be in this format:
svnUserId = First Last
This process will take a little while, especially for large repositories. When that’s done, git-svn will have created a new MyProject folder containing the full repository.
We can verify its contents:
$ cd MyProject $ ls -la $ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [svn-remote "svn"] url = https://my.svn.repository.com/MyProject fetch = trunk:refs/remotes/trunk branches = branches/*:refs/remotes/* tags = tags/*:refs/remotes/tags/*
Note that the location of our remote SVN repository is stored in the .git/config - this allows git-svn to commit any changes you make back to the main SVN repository if you want to (how to do this is well explained in the introduction to git-svn for Subversion deserters).
2. Creating a remote git repository
However, our aim is to replace our existing remote SVN repository with a remote git repository; to do so, we first need to create an empty git repository on the remote machine, which we will then upload the repository we just created locally. This assumes that git-core is installed on the remote machine:
$ ssh email@example.com $me@remote>: mkdir git $me@remote>: cd git $me@remote>: mkdir MyProject.git $me@remote>: cd MyProject.git $me@remote>: pwd /home/me/git/MyProject.git $me@remote>: exit
Note the output of pwd - this will be the path we will use to access the remote repository from our local box.
3. Configure the local repository
Now that we have created the remote repository, we can upload our local repository to its remote location. First, back on our local machine, we need to tell git where the remote repository is located:
$ git remote add origin ssh://firstname.lastname@example.org/home/me/git/MyProject.git
- remote add: adds a remote location
- origin: the name of the remote location
Next, we need to tell git who we are:
$ git config --add user.name "First Last" $ git config --add user.email email@example.com
Let’s have a quick look at our configuration:
$ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [svn-remote "svn"] url = https://secure2.svnrepository.com/s_zcrar70/MetisseV2 fetch = trunk:refs/remotes/trunk branches = branches/*:refs/remotes/* tags = tags/*:refs/remotes/tags/* [user] name = First Last email = firstname.lastname@example.org [remote "origin"] url = ssh://email@example.com/home/me/git/MyProject.git fetch = +refs/heads/*:refs/remotes/origin/*
Note the user information and the remote location have been added to the config file.
4. Uploading to the remote git repository
That should be it - we’re ready to upload the local repository to the remote location. It’s as simple as:
$ git push origin master
This will upload the contents of the master branch to the origin remote repository. We will also want to upload any tags and branches from subversion:
$git branches -r branch1 branch2 tags/tag1 tags/tag2 $git push origin branch1:refs/heads/branch1 $git push origin branch2:refs/heads/branch2 $git push origin tags/tag1:refs/tags/tag1 $git push origin tags/tag2:refs/tags/tag2
A note on the commands here:
- git branches -r: list all remote branches
- git push origin :/refs/heads/: push the local branch to the remote repository, creating a new remote branch of the same name
- git push origin tags/:/refs/tags/: push the local tag to the remote repository, creating a new remote tag of the same name
5. Accessing our new remote git repository
The contents of our local git repository were retrieved from SVN; now that we’ve uploaded that to our new remote git repository, we can get rid of the intermediary local repository we were working on, and begin using with our remote git repository in earnest:
$ cd .. $ rm -rf MyProject $ mkdir MyProject $ cd MyProject $ git init $ git config --add user.name "First Last" $ git config --add user.email firstname.lastname@example.org $ git remote add origin ssh://email@example.com/home/me/git/MyProject.git $ git pull origin master $ git branch -a * master origin/master origin/branch1 origin/branch2 $ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [user] name = First Last email = firstname.lastname@example.org [remote "origin"] url = ssh://email@example.com/home/me/git/MyProject.git fetch = +refs/heads/*:refs/remotes/origin/*
That’s it! We’ve just pulled the master branch from our remote git repository, and at this stage, we are ready to start working with git locally. Note that when we ask git to tell us about all of the branches it knows about, it no longer mentions the SVN branches that we are no longer interested in.
We can now edit files, commit changes, and then push those changes to our remote repository; a good place for SVN users to start learning how to do this is the Git-SVN Crash Course
Note: if you have git-svn installed on the remote machine, you can use git-svn to clone the repository from SVN directly on the remote machine using the –bare option (which gets just the repository, without the files). You can then use git pull to get a local copy once the remote information has been set up; this involves less steps, and would likely be a little quicker. Unfortunately, I didn’t have access to git-svn remotely, or access to install it, so this wasn’t an option for me.
The following guides were helpful to me:
Setting up a new remote git repository - Toolman Tim
An introduction to git-svn for Subversion deserters
Converting a Subversion repository to git - Ruby Forums
Converting Subversion repositories to Git - Redline Software