A feature of (q)bzr I really love

Bazaar lets you compare branches. Not just branches from the same repository, i.e. all stored in the same .bzr/ folder, but arbitrary branches that may (or may not) have some common history. All those years of typing code for fun and profit, and staring at directed acyclic graphs wandering where the heck that stupid C macro that breaks the build was introduced, might have changed my sense of “awesome”.
But ladies and gentlemen, this is pretty much awesome.

Let me show you an example.

Playing the TIAS game with bazaar

TIAS is Try It And See, no less no more. I did some TIAS in another post about Mercurial, and I am doing it again. Let’s get this party started.

First thing we create a repository and fork it two times. Actually in bzr the correspondence between repositories and branches can be one to one, with bzr init, or one to many, with bzr init-repo. The latter creates what is called a “shared repository”, i.e. a repository that can hosts many branches. This is indeed the way git and mercurial work; the former option is a bzr-only thing. Let’s stick to the one-repo-one-branch setup; it doesn’t make a big difference for the purpose of this post, and it requires less typing.

$ bzr init b
Created a standalone tree (format: 2a)
$ bzr branch b c1
Branched 0 revisions.
$ bzr branch b c2
Branched 0 revisions.

We now switch to c1, enter a couple of commits, and push them back to the parent branch, which is b/.

$ cd c1

/c1$ echo 'hello world!' > src1.txt
/c1$ bzr add src1.txt
adding src1.txt
/c1$ bzr commit -m "initial import"
Committing to: c1/
added src1.txt
Committed revision 1.

/c1$ echo 'hello world!\nIt is gonna be a nice day.' > src1.txt
/c1$ bzr commit -m "added optimism."
Committing to: c1/
modified src1.txt
Committed revision 2.

/c1$ bzr push :parent
All changes applied successfully.
Pushed up to revision 2.

Some time later, developer c2 enters the scene, retrieves the current content of b/ and makes a commit. He doesn’t push back to b/, because he’s not quite done yet.

$ cd ../c2/

/c2$ bzr pull
Using saved parent location: b/
+N  src1.txt
All changes applied successfully.
Now on revision 2.

/c2$ echo "That's a nice Tnettenba" > src2.txt
/c2$ bzr add src2.txt
adding src2.txt
/c2$ bzr commit -m "added joke"
Committing to: c2/
added src2.txt
Committed revision 3.

c1 gets back to work: he continues to develop his thing.

/c2$ cd ../c1

/c1$ echo 'voodoo atchoo to you too' > src3.txt
/c1$ bzr add src3.txt
adding src3.txt
/c1$ bzr commit -m 'thank you!'
Committing to: c1/
added src3.txt
Committed revision 3.

The release engineer, who has direct access to the server where b/ is stored, has been thinking on how to fix that shell script that handles the deployment. He finally figures it out; he’s in a hurry, and doesn’t want to branch and merge — he commits directly on b/. It happens.

$ cd ../b/

/b$ echo 'the grumpy cat says it had fun, once' > src4.txt
/b$ bzr add src4.txt
adding src4.txt
/b$ bzr commit -m 'that never happened.'
Committing to: b/
added src4.txt
Committed revision 3.

It’s c1‘s turn to play now. He had a coffee with c2; they talked about the code and c1 realizes he needs the new feature that c2 just committed. So he merges with c2, and then goes a little further.

/c1$ bzr merge ../c2
+N  src2.txt
All changes applied successfully.
/c1$ bzr commit -m "thanks c2, that was neat"
Committing to: c1/
added src2.txt
Committed revision 4.

/c1$ echo 'if (0 == a);' > src6.txt
/c1$ bzr add src6.txt
adding src6.txt
/c1$ bzr commit -m 'Zero the value is not. Yoda style.'
Committing to: c1/
added src6.txt
Committed revision 5.

It’s almost time to leave, and c2 has just the time to fix that little annoying bug before heading home.

/c1$ cd ../c2

/c2$ echo 'NaNNaNaNNaNaN' > src5.txt
/c2$ bzr add src5.txt 
adding src5.txt
/c2$ bzr commit -m 'Batman. I need Batman.'
Committing to: c2/
added src5.txt
Committed revision 4.

The sweet pretty pictures

The day after c1 and c2 get back to work, chit-chat a little, and realize that they don’t know exactly how their two branches relate. Ok, somebody pushed, somebody merged… but they’d like to see it crystal clear, to anticipate all the problems that will arise when, next wednesday, all lines are going to be merged into the production code. More over, they’ve no idea that the release engineer jumped in and added stuff directly to the reference repo b/. What do they do?
Easy peasy: bzr qlog b c1 c2.
The amazing command

bzr qlog <branch_1> <branch_2> ... <branch_n>

shows what all branches have in common, who diverged, who pushed to whom, everything. And recall that we’re talking of branches that reside in different repositories. Too good! This is what the command

bzr qlog b c1 c2

would show:

Isn’t that pretty?
Just for the sake of taking some screenshots and messing around with gimp, I’ll show you that the branches you compare can be totally, and I say totally, unrelated. Here is what you get if you compare the trunk of bzr itself with the latest mysql-server codebase via

bzr qlog lp:bzr lp:mysql-server

I had to shrink it a little bit, as you can imagine; of course the two don’t share a thing, but that’s just for the fun of the abuse:

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>