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
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
$ 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.
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
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?
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
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: