Bazaar, the git way

Back at the Ubuntu Platform Rally last week, I’ve pestered some of the Bazaar team with questions about co-location of branches in the same directory with Bazaar. The great news is that this seems to be really coming for the next release, with first-class integration of the feature in the command set. Unfortunately, though, it’s not quite yet ready for prime time, or even for I’m-crazy-and-want-this-feature time.

Some background on why this feature turns out to be quite important right now may be interesting, since life with Bazaar in the past years hasn’t really brought that up as a blocker. The cause for the new interest lies in some recent changes in the toolset of the Go language. The new go tool not only makes building and interacting with Go packages a breeze, but it also solves a class of problems previously existent. For the go tool to work, though, it requires the use of $GOPATH consistently, and this means that the package has to live in a well defined directory. The traditional way that Bazaar manages branches into their own directories becomes a deal breaker then.

So, last week I had the chance to exchange some ideas with Jelmer Vernooij and Vincent Ladeuil (both Bazaar hackers) on these problems, and they introduced me to the approach of using lightweight checkouts to workaround some of the limitations. Lightweight checkouts in Bazaar makes the working tree resemble a little bit the old-style VCS tools, with the working tree being bound to another location that actually has the core content. The idea is great, and given how well lightweight checkouts work with Bazaar, building a full fledged solution shouldn’t be a lot of work really.

After that conversation, I’ve put a trivial hack together that would make bzr look like git from the outside, by wrapping the command line, and did a lightning talk demo. This got a few more people interested on the concept, which was enough motivation for me to move the idea forward onto a working implementation. Now I just needed the time to do it, but it wasn’t too hard to find it either.

I happen to be part of the unlucky group that too often takes more than 24 hours to get back home from these events. This is not entirely bad, though.. I also happen to be part of the lucky group that can code while flying and riding buses as means to relieve the boredom (reading helps too). This time around, cobzr became the implementation of choice, and given ~10 hours of coding, we have a very neat and over-engineered wrapper for the bzr command.

The core of the implementation is the same as the original hack: wrap bzr and call it from outside to restructure the tree. That said, rather than being entirely lazy and hackish line parsing, it actually parses bzr’s –help output for commands to build a base of supported options, and parses the command line exactly like Bazaar itself would, validating options as it goes and distinguishing between flags with arguments from positional parameters. That enables the proxying to do much more interesting work on the intercepted arguments.

Here is a quick session that shows a branch being created with the tool. It should look fairly familiar for someone used to git:

[~]% bzr branch lp:juju
Branched 443 revisions.

[~]% cd juju
[~/juju]% bzr branch
* master

[~/juju]% bzr checkout -b new-feature
Shared repository with trees (format: 2a)
shared repository: .bzr/cobzr
Branched 443 revisions.
Branched 443 revisions.
Tree is up to date at revision 443.
Switched to branch: /home/niemeyer/juju/.bzr/cobzr/new-feature/

[~/juju]% bzr branch other-feature
Branched 443 revisions.

[~/juju]% bzr branch
* new-feature

Note that cobzr will not reorganize the tree layout before the multiple branch support is required.

Even though the wrapping is taking place and bzr’s –help output is parsed, there’s pretty much no noticeable overhead given the use of Go for the implementation and also that the processed output of –help is cached (I said it was overengineered).

As an example, the first is the real bzr, while the second is a link to cobzr:

[~/juju]% time /usr/bin/bzr status
/usr/bin/bzr status 0.24s user 0.03s system 88% cpu 0.304 total

[~/juju]% time bzr status
bzr status 0.19s user 0.08s system 88% cpu 0.307 total

This should be more than enough for surviving comfortably until bzr itself comes along with first class support for co-located branches in the next release.

In case you’re interested in using it or are just curious about the command set or other details, please check out the web page for the project:

This entry was posted in Conference, Design, Go, Project, Python, RCS. Bookmark the permalink.

8 Responses to Bazaar, the git way

  1. Martin Pool says:

    This looks pretty similar to bzr-colo – how does that differ?

  2. ?ukasz says:

    I’ve been using bzr-colo plugin for almost a year now. So far no issues with it.

  3. From looking at the code, it seems it does indeed do pretty much the same thing as bzr-colo, except it stores branches in .bzr/cobzr rather than .bzr/branches as bzr-colo does.

  4. Sorry, I forgot to mention it here, but the page does mention it at the top:

    There’s also a plugin (link) available offering similar functionality. cobzr differs from the plugin by using a command set similar to git and by hiding away the visible difference between a branch with co-location and one without. Commands always work, and the tree is adapted to co-location the first time multiple branches are requested, so usage is simpler and more natural (to its author, at least ;-). That said, see the considerations below.

  5. Oh, and of course it integrates with the “normal” commands rather than adding a new set. That’s pretty neat.

    We’ll make sure to obsolete it before long though, by finishing the colocated branch support in core. ;-)

  6. Jelmer, I hope it’s clear that I’m looking forward to that! :-)

    Regarding the use of .bzr/branches, I explicitly avoided it because I noticed you were using it for the upcoming 2.5 functionality. .bzr/cobzr felt like it wouldn’t cause trouble to anyone.

  7. Argh, race condition. I didn’t see your reply until I posted mine.

    It would be nice if cobzr could back off if .bzr/branches existed, so that it will seamlessly work with the new colocated branch support if that has been enabled on a bzr control directory.

  8. Jelmer, it sounds like a good idea indeed. Will put that in the next release.

Leave a Reply

Your email address will not be published. Required fields are marked *