Migrating from SVN to GIT for Bitbucket

  •  

First of all, retrieve the required package to enable the git svn command:

apt-get install git-svn

Preparation

Standardise your SVN layout

If you're not using separate folders for tags and/or branches, you can just skip to the next setion.

As described in Bitbucket's SVN Tutorial, it's best to use a standardised configuration before starting the migration. Otherwise you'd have to manually change the config file to avoid errors during the last (cleanup) step. The ideal situation is to have a trunk, branches and tags layout. For example, I used the following commands:

svn rename master trunk
mkdir branches
svn add branches
svn rename some-feature branches/some-feature
svn commit

Creating an authors file

If you want your commits to be assigned to the proper names, you can use Atlassian's Migration Script, or simply create the authors.txt file with the following structure:

svnuser = User Realname <user@mail.to>
svnother = Other Name <other@mail.me>

If you find this too much hassle, just leave the file and the --authors-file argument away from the comments below.

Execution

Clone to Git

Then, the actual cloning to git. If you're using the standard layout as described above, you can simply use the --stdlayout option, otherwise you have to specify trunks, branches and/or tags manually using the --trunk, --branches and --tags options:

# Standardised layout
git svn clone --stdlayout --authors-file=authors.txt svn://your.server.tld/repo /target/path

# Non-standard layout
git svn clone --trunk="/master" --branches="/projects" --tags="/releases" --authors-file=authors.txt svn://your.server.tld/repo git_repo_name

# Linear layout (no branches or tags)
git svn clone --authors-file=authors.txt svn://your.server.tld/repo /target/path

Keep in mind the cloning process is aggressively — desperately — trying to find as much information as it can, which results in errors flying all around. The best suggestion I have is to simply see what the result looks like and change your parameters accordingly. For testing, you could specify a subset of revisions, for example: -r 1000:HEAD.

Cleaning up Git

If you were using branches and/or tags in your svn repository, the resulting Git repository set these up a remote branches. If you plan on syncing your git repository back to svn, these remote branches help a lot and this section can be skipped.

Atlassian's tutorial suggests using a java-tool, but this tool isn't maintained anymore and therefore doesn't work as it should. So, we'll do it manually.

Using slightly modified commands from Sailmakers' great tutorial, we can manually make the remote branches and tags branches:

# Making remote branches local
for branch in `git branch -r | grep -vE "trunk|tags" | cut -d/ -f2`; do
  git branch $branch origin/$branch
done

# Making remote tags local
for tag in `git branch -r | grep "tags/" | cut -d/ -f3`; do
  git tag -a -m"Converting SVN tag $tag" $tag remotes/origin/tags/$tag
done

To check if all worked ok, use:

# List all tags
git tag -l

# List all branches
git branch -a

Adding Bitbucket as origin

Now to push it all to Bitbucket, first create a new GIT project on bitbucket.org and use the suggested commands below "I have an existing project", they'll look something like this:

git remote add origin git@bitbucket.org:username/projectname.git
git push -u origin master
git push --all
git push --tags

Conclusion

Even though this process is quite cumbersome, it'll migrate your svn history to git, keeping all logs, branches and tags in tact. That said, getting the git svn clone commands set up properly can be quite cumbersome. Nonetheless, once you succeed, you can finally benefit of the — in my opinion — improved workflow git offers.