26. Mar 2013

David Roth

4 Min.

We used Bazaar since 2009 and were quite happy with it until bzr started to make serious problems in our daily business mostly because of some annoying long standing bugs and stability problems:

  • Bazaar Explorer randomly freezed many times a day
  • Bazaar PHPStorm Integration with lots of freezes and bad performance
  • No Support in Visual Studio, no Support in Monodevelop

Beside the massive performance problems it was also clear that Git has become the most commonly used DVCS in the open source community. This was also heavily influenced by GitHub as it has taken the world by storm.

After some internal discussion we decided to break up with Bazaar and completely switch to Git. This would give use the following benefits:

  • Stable and full support in all major development environments and operating systems we use in our business (PHPStorm, Visual Studio, Monodevelop on Ubuntu, Windows and Mac OS X)
  • No more freezes and performance issues
  • One version control system for both internal closed source projects and open source projects
  • Possibility to also host our internal projects on GitHub with a private plan

The basic migration to Git is possible with the Fastimport/FastExport file-format. So in order to migrate a branch to git you just have to run a simple command:

bzr fast-export --git-branch=master | git fast-import

While this works very well it has one major drawback: lost bug tracker information.

Migrating Bazaar Commit Metadata

During our time with bazaar we extensively used the "bug tracker metadata" feature (http://doc.bazaar.canonical.com/bzr.dev/en/user-reference/bugs-help.html). So every bug-fix commit included the ID to the corresponding Mantis bug-id. Bazaar stores this information in a separate commit-property, which is not available in Git.

bzr-fastexport does not export these metadata properties by default, however it is possible to include them with the "--no-plain" argument:

bzr fast-export --git-branch=master --no-plain | git fast-import

Because Git does not support bug metadata the command crashes with the following error:

My first hope was to get some support from the community, so I put a question on StackOverflow.

Because there was no response and losing all these bug-ids was no option for us, I wrote a fast-export stream-rewriter which is capable of rewriting the stream in a format that Git understands but with all our bug id infos included.

The fast-import file stream format

The fast-import stream is a mixed command/data stream with UTF-8 encoded commit message data and plain binary commit data.

Here is a sample commit from the Chive import-stream with --no-plain:

commit refs/heads/master
mark :301
committer David Roth  1268213982 +0100
data 25 AJAX requests keep failing
from :300
property branch-nick 5 trunk
property bugs 39 https://launchpad.net/bugs/533882 fixed
M 644 inline protected/db/ActiveRecord.php
data 3415

An example command containing the desired bug info is the following:

property bugs 39 https://launchpad.net/bugs/533882 fixed

So in order to keep this bug-id the rewriter basically executes the following steps:

  1. Parse commits from input stream
  2. Check if a commit contains a property bugs command
  3. Parse the bug-id and modify the commit-message with the extracted bug-id
  4. Exclude other unsupported bzr-fastexport only commands ("feature", "property branch nick")

After these steps the previous command has been rewritten into this:

commit refs/heads/master
commit refs/heads/master
mark :301
committer David Roth  1268213982 +0100
data 40 Bug #533882: AJAX requests keep failing
from :300
M 644 inline protected/db/ActiveRecord.php
data 3415


My bzr-to-git migration script operates on basic .NET Stream classes, so the performance is excellent. Parsing and rewriting our 830 MB Commit-History of Ribbl takes less than 4 seconds.

Getting the code

If you also want to switch to Git from Bazaar you can get the migration-script from the following gist-location and adapt it to your requirements:

The formatter is available in this gist: https://gist.github.com/davidroth/5243901 The code is published under the MIT licence.