Using OpenSSH with bzr

One of the transports available in bzr is sftp. This is implemented using the Paramiko SSH and SFTP library. Unfortunately there are a few issues I experienced with the code:

  • Since it is an independent implementation of SSH, none of my OpenSSH settings in ~/.ssh/config were recognised. The particular options I rely on include:
    1. User: when the remote username doesn’t match my local one. One less thing to remember when connecting to a remote machine.
    2. IdentityFile: use different keys to access different machines.
    3. ProxyCommand: access work machines that are behind the firewall.
  • Paramiko does not currently support SSH compression. This is a real pain for larger trees.

The easiest way to fix all these problems would be to use OpenSSH directly, so wrote a small plugin to do so. I decided to follow the model used to do this in gnome-vfs and Bazaar 1.x: communicate with an ssh subprocess via pipes and implement the SFTP protocol internally.

Since SFTP is layered fairly cleanly on top of SSH, and the paramiko code was also quite modular, it was possible to use the paramiko SFTP implementation with openssh. The result is a small plugin that monkey-patches the existing SFTP transport:

Just copy into the ~/.bazaar/plugins directory, and use bzr as normal. The compression seems to make a noticable difference to performance, but it should be possible to improve things further with a pipelined SFTP client implementation.

Of course, the biggest performance optimisation will probably come from the smart server, when that is implemented.

Comparison of Configs/Aliases in Bazaar, CVS and Subversion

When a project grows to a certain size, it will probably need a way to share code between multiple software packages they release. In the context of Gnome, one example is the sharing of the libbackground code between Nautilus and gnome-control-center. The simplest way to do this is to just copy over the files in question and manually synchronise them. This is a pain to do, and can lead to problems if changes are made to both copies, so you’d want to avoid it if possible. So most version control systems provide some way to share code in this way. As with the previous articles, I’ll focus on Bazaar, CVS and Subversion

Unlike the common operations each system implements this feature in a different way, so I’ll go over each one in turn and then compare them.


When you run the “cvs checkout module” command, CVS will look in the CVSROOT/modules file for the repository. For example, the file might contain the following:

module foobar

This would tell CVS to check out the foobar directory from the repository into a directory named module when the user asks for module. If no entry is found for a particular name, the directory by that name is checked out from the repository.

To compose multiple modules into a single working copy, the ampersand syntax can be used:

module foo &bar &baz
bar othermodule/bar

With this modules file, “cvs checkout module” would give the following working copy:

Working Copy Repository
module foo
module/bar othermodule/bar
module/baz baz

Operations like tag, commit, update, etc will descend into included modules, so for the most part a user can treat the resulting working copy as a single tree. If a particular branch tag exists on all the included modules, you can even check out a branch of the combined working copy. There are some problems with the support though:

  • While “cvs update” will update the working copy, it won’t take into account any changes in CVSROOT/modules.
  • If you’ve only got write access to part of the repository, and can’t write to CVSROOT/modules, then you can’t change configurations.
  • While CVS lets you check out old versions of code, you still use the latest version of CVSROOT/modules. This can make it difficult to check out historical versions of the tree.
  • Since “cvs tag” descends into included modules, you can end up with many branch tags on some modules. For instance, the gnome-common/macros directory in Gnome CVS has 282 branch tags, which makes it almost impossible to feed fixes to all those branches.


Rather than a single repository-wide file describing the module configuration for checkouts, Subversion makes use of the svn:externals property on directories.

Any directory can have such a property attached. Each line in the property is of the form:

subdir [-rrevnum] absolute-uri-of-tree-to-include

This will check out each the given tree at the given sub dir when ever “svn checkout” or “svn update” are used. However unlike CVS, “svn commit” will not descend into the included modules.

Some of the benefits of this approach include:

  • Inclusions can be placed close to the location they are included.
  • It reduces the permissions problems: if you can commit to the directory where the inclusion will occur, you can add the inclusion.
  • Can include modules from other repositories. In this case, it is actually useful that “svn commit” doesn’t descend into the included module because it is likely that the user won’t have write access to the external modules.
  • When checking out a historic version of the module, the historic version of the svn:externals properties get used.

Some of the down sides to the approach include:

  • Module inclusion directives can be scattered throughout the tree. There isn’t a single place to look for such directives.
  • When including something from the same repository, you still need to use an absolute URI to identify the module. It is not uncommon for committers to use a different URI to access the repository to those who only have read access (e.g. svn+ssh://hostname for committers, svn://hostname or http://hostname for read-only users). So which URI do you use in the svn:externals property? You’ll need to choose between a tree that read-only users can’t check out or a tree that committers can’t commit to …
  • If you want to branch a set of related modules in the repository, you’ll need to alter the svn:externals properties to point at the branched versions of the modules. When performing merges back to the mainline, you need to make sure you don’t merge the svn:externals property changes.
  • When checking out historic versions, although historic svn:externals definitions get used, you will get the up-to-date versions of the included modules unless a particular revision of the included module was specified in the property.
  • If the hosting arrangements for an included module change, the historical values of svn:externals properties will be invalid.


The module inclusion system in Bazaar is handled through “configurations”. These are simple files stored in a branch with lines of the form:

subdirectory archivename/branchname[--patch-NNNN]

After checking out a branch, you can check out the various included modules by running the following command from the base of the working copy:

baz build-config file-name

To update a working copy and all the included modules, you need two commands:

baz update
baz build-config -u file-name

(the -u flag is only available in the 1.5 prereleases. Previously you needed a command like “baz cat-config file-name | xargs -n2 baz update -d“).

The name of the configuration file is not special, and it is possible to have multiple configurations stored in a single branch. In fact it is common to have a branch that stores nothing but configurations, and assemble the source tree in a subdirectory.

One common use of multiple configs is similar to the use of non-branch tags in CVS: recording a particular configuration used for a particular release. This can be done by taking a snapshot of the configuration, which adds fixed revision numbers to the branches checked out:

baz cat-config --snap development.config > release-0.42.config

If anyone builds this configuration, they will see the tree as it was when that snapshot was taken. Some benefits of this system include:

  • It is easy to maintain multiple configurations for a set of branches.
  • Since configurations are stored in the same way as other files on the branch, anyone can modify them (either by committing to the branch, or by creating a new branch and making the change there).
  • Use of the arch namespace to identify branches, so is somewhat immune to branch location changes (it is still vulnerable to referenced branches disappearing altogether).

Some of the down sides of the approach include:

  • Requires the user to run a second command after checking out the branch containing the configuration.
  • No standard name for configurations, so the user needs to know the config file name in addition to the branch name when checking things out.


Here is a summary of how the three systems stand up against each other in this respect:

  CVS Subversion Bazaar
Who can change configs? Committers to CVSROOT Committers Anyone
Build historic configs? No Yes Sort of (snapshot configs)
Supports multiple parallel configurations of same code? Yes Yes Yes
commit command crosses module inclusion boundaries? Yes No No
Configs built by checkout command? Yes Yes No
Configs built by update command? No Yes No
Resistant to project hosting changes? Yes No Yes
Same config usable for committers and read-only users? Yes Yes for DAV access
No for svn+ssh:// access

Each system is slightly different with its benefits and problems. It isn’t particularly surprising then that configs are not handled well by the various version control migration scripts. For example, the cvs2svn script doesn’t handle them at all (e.g. the KDE Subversion repository doesn’t contain any svn:externals properties in historic versions migrated from CVS).

Version control discussion on the Python list

The Python developers have been discussing a migration off CVS on the python-dev mailing list. During the discussion, Bazaar-NG was mentioned. A few posts of note:

I’m going to have to play around with bzr a bit more, but it looks very nice (and should require less typing than baz …)

Version Control Workflow

Havoc: we are looking at ways to better integrate version control in Launchpad. There are many areas that could benefit from better use of version control, but I’ll focus on bug tracking since you mentioned it.

Take the attachment handling in Bugzilla, for instance. In non-ancient versions, you can attach statuses to attachments such as “obsolete” (which has some special handling in the UI — striking out obsolete attachments and making it easy to mark attachments as obsolete when uploading a new attachment). This makes it easy to track and manage a sequence of patches as a fix for a bug is developed (bug 118372 is a metacity bug with such a chain of patches).

If you look at this from a version control perspective, this sequence of patches forms a branch off the mainline of the software, where each newly attached patch is a new revision. The main differences being:

  • No explicit indication of what the patch was made against (code base or revision), or what options were used to create the patch.
  • No linkage between successive patches (can be a bit confusing if multiple patch series are attached to the same bug report).

So why not just use real version control to manage patches in the bug tracker? The big reason for projects using CVS or Subversion is that only authenticated users can create branches in the repository, and you don’t want to require contributors to ask permission before submitting fixes.

So this is an area where a distributed version control system can help: anyone can make a branch, so potential contributors don’t need permission to begin working on a bug. This also has the benefit that the contributors get access to the same tools as the developers (which is also helpful if they ever become a regular developer).

Now if you combine this with history sensitive merging and tell the bug tracker what the mainline branches of the products are, you can do some useful things:

  • Try and merge the changes from the bug fix branch onto the mainline, and see if it merges cleanly. This can tell a developer at a glance whether the patch has bitrotted. This could also be used to produce an up to date diff to the mainline, which can aid review of the changes.
  • Check if the bug fix branch has been merged into the mainline. No need for developers to manually flag the attachment as such.

We discussed some of these features in the context of Launchpad at the recent Brazil meeting.

Bryan’s Bazaar Tutorial

Bryan: there are a number of steps you can skip in your little tutorial:

  1. You don’t need to set my-default-archive. If you often work with multiple archives, you can treat working copies for all archives pretty much the same. If you are currently inside a working copy, any branch names you use will be relative to your current one, so you can still use short branch names in almost all cases (this is similar to the reason I don’t set $CVSROOT when working with CVS).
  2. If you have a directory which contains only the files you want to import into your Bazaar archive, the following command will add them all, and convert the directory into a Bazaar working copy:
    cd background-channels
    baz import -a

    No need for init-tree, add or commit.

  3. Running archive-mirror in your working copy will mirror that archive, so doesn’t need my-default-archive set.
  4. Other people probably don’t want to set your archive as their default. Also, they can ommit the register-archive call entirely:
    baz get

    This checks out the branch, and registers the archive as a side effect.

  5. If you want to find out what is inside an archive, the following command is quite convenient:
    baz abrowse

Some things you might want to do:

  1. If you have a PGP key, create a signed archive. This will cryptographically sign all revisions. When people checkout your branches, the signatures get checked automatically (this is useful if the server hosting your mirror gets broken into and you need to verify that nothing has been tampered with). If you have already created the archive, you can turn on signing with baz change-archive (remember to update the mirror archive too).
  2. If you turn on signing, consider using a PGP agent like gnome-gpg. You can configure it in ~/.arch-params/archives/defaults.
  3. It is customary to name the archive directory the same as the archive name. This has the benefit that the branch name matches the last portion of the URL.
  4. If you haven’t set up a revision library, you should do so:
    mkdir ~/.arch-revlib
    baz my-revision-library ~/.arch-revlib
    baz library-config --greedy --sparse ~/.arch-revlib

Merging In Bazaar

This posting follows on from my previous postings about Bazaar, but is a bit more advanced. In most cases you don’t need to worry about this, since the tools should just work. However if problems occur (or if you’re just curious about how things work), it can be useful to know a bit about what’s going on inside.

Changesets vs. Tree Snapshots

A lot of the tutorials for Arch list “changeset orientation” as one of its benefits over other systems such as Subversion, which were said to be based on “tree snapshots”. At first this puzzled me, since from my mathematical background the relationship between these two concepts seemed the same as the relationship between integrals and derivatives:

  • A changeset is just the difference between two tree snapshots.
  • The state of a tree at a particular point in just the result of taking the initial tree state (which might be an empty tree), and applying all changesets on the line of development made before that point.

The distinction isn’t clear cut in the existing tools either — Subversion uses changesets to store the data in the repository while providing a “tree snapshot” style view, and Bazaar generates tree snapshots in its revision library to increase performance of some operations.

So the distinction people talk about isn’t a simple matter of the repository storage format. Instead the difference is in the metadata stored along with the changes that describes the ancestry of the code.

Changesets and Branching

In the simple case of a single branch, you end up with a simple series of changesets. The tree for each revision is constructed by taking the last revision’s tree and applying the relevant changeset. Alternatively, you can say that the tree for patch-3 contains the changesets base-0, patch-1, patch-2 and patch-3.

base-0 → patch-1 → patch-2 → patch-3

Branching fits into this model pretty well. As with other systems, a particular revision can have multiple children. In the diagram below, the trees for both patch-2 from the original branch and patch-1 from the new branch “contain” base-0 and patch-1 from the original branch. Any apparent asymmetry is just in the naming and storage locations — both revisions are branches are just patches against the same parent revision.

base-0 → patch-1 → patch-2 → patch-3, patch-1 → patch-1 → patch-2

So far, there’s no rocket science. Nothing that Subversion doesn’t represent. Pretty much every version control system under the sun tracks this kind of linear revision ancestry (as can be seen using svn log or similar). The differences really only become apparent when merges are taken into consideration.


Just as a particular revision can have multiple child revisions (a.k.a. branching), a tree can have multiple parent revisions when merges occur. When you merge two revisions, the result should contain all the changes that exist in the parent revisions.

base-0 → patch-1 → patch-2 → patch-3 → patch-4, patch-1 → patch-1 → patch-2 → patch-4

In the above diagram, we want to merge the changes made on the second branch back into the original one. The usual way to merge changes goes something like this:

  1. Identify the most recent common ancestor of the two revisions.
  2. Take the difference between one of the revisions to merge and apply those changes to the other revision.

If the changes on the two branches are to different parts of the tree, this process can be done without any extra user intervention. If the two branches touch the same bits of code, the conflicts will have to be resolved manually.

It is important to pick the most recent common ancestor, otherwise the real changes in the two branches will get mixed in with changes common to the two branches, which can result in spurious merge conflicts.

In this particular case, it is obvious which common ancestor to use: patch-1 from the original branch. In Arch, the result of the merge is represented as a changeset on the original branch that contains the changes found on the second branch. In addition to the changes, it adds some metadata (known as patch logs) that records that patch-1 and patch-2 from the second branch have been merged in. This becomes important when performing future merges between the two branches.

Repeated Merges

While it was possible to pick the correct merge ancestor in the previous example using just the linear revision ancestry of the two branches, that isn’t true for subsequent merges between the two branches. Consider the following merge that results in patch-6 on the original branch:

base-0 → patch-1 → patch-2 → patch-3 → patch-4 → patch-5 → patch-6, patch-1 → patch-1 → patch-2 → patch-3 → patch 4 → patch-5, patch-2 → patch-5, patch-4 → patch-6

Here the best merge ancestor to use is patch-2 on the second branch. However, without the record of the previous merge, the same ancestor as the previous merge would be chosen (which is what CVS will do by default with repeated merges).

While the above ancestor could be selected by just recording when you last merged with a particular branch, that is not sufficient when there are merges between more than two branches.

More Than Two Branches

Below is a fairly simple example involving three branches, where some changes have been merged from the third branch (yellow) into the original branch (cyan) and the second branch (magenta). Finally, there is a merge between the magenta and cyan branches.

base-0 → patch-1 → patch-2 → patch-3 → patch-4 → patch-5 → patch-6, patch-1 → patch-1 → patch-2 → patch-3 → patch 4 → patch-5, patch-1 → patch-1 → patch-2 → patch-3 → patch 4 → patch-5, patch-2 → patch-3, patch-3 → patch-5, patch-4 → patch-6

For this last merge, there are a number of possible merge ancestors. If we ignore the yellow branch, the latest common ancestor is the initial branch point. This would result in merging the changes in patch-1, patch-2, patch-3 and patch-4 from the second branch into the patch-5 tree on the original branch. However, this is likely to result in a number of conflicts, since both branches contain changes merged from the yellow branch, which are going to overlap.

The better common ancestor ancestor to choose in this case is patch-2 on the yellow branch, which avoids the common changes.

Bazaar’s merge command will handle this kind of merge ancestry just fine (something that isn’t true for of the older tla star-merge algorithm).


This article doesn’t cover all aspects of branching and merging with Bazaar. One aspect I have completely ignored is the concept of “cherry picking”. This refers to applying a particular change to a tree, without the other changesets that exist on that branch. Cherry picking is mostly orthogonal to standard merging — in fact, one of the complications in merge ancestor selection is that it needs to ignore cherry picked patches.

Network effects also come into play here — if you make your code available as an Arch branch, then Bazaar is more useful to others since they can branch and merge with your archive (and the reverse holds too). The Ubuntu Arch imports certainly help here, but to get the full advantage of the advanced merge capabilities both sides need to be tracking history.

Bazaar (continued)

I got a few responses to the comparison between CVS, Subversion and Bazaar command line interfaces I posted earlier from Elijah, Mikael and David. As I stated in that post, I was looking at areas where the three systems could be compared. Of course, most people would choose Arch because of the things it can do with it that Subversion and CVS can’t. Below I’ll discuss two of those things: disconnected development and distributed development. I’ll follow on from the examples in the previous post.

Disconnected Development

Disconnected development allows you to continue working on some code while not having access to the main repository. I hinted at how to do this in the previous post, but left out most of the details. The basic steps are:

  1. Create an archive on your machine
  2. Branch the module you want to work on into your local archive.
  3. Perform your development as normal
  4. When you connect again, switch back to the mainline, merge your local branch and commit the changes.

To create the local archive, you follow the same procedure as for creating the original archive. Something like this:

mkdir ~/archives
baz make-archive --signed ~/archives/

This creates an archive named (archive names are required to be an email address, optionally followed by some extra info) stored in the user’s home directory.

Now we can create a branch in the local archive. From a working copy of the mainline branch, run the following command:

baz branch

It was necessary to specify an archive name in this call to baz branch, because the branch was being created in a different archive to the one the working copy was pointing at. This leaves the working copy pointing at the new branch, so you can start working on it immediately.

You can commit as many revisions as you want, and compare to other revisions on the branch.

When you have access to the main repository again, it is trivial to merge your changes back into the mainline:

baz switch
baz merge
fix conflicts, if any exist, and mark them resolved
baz commit -s 'merge changes from'

You can then ignore the branch in the archive, or continue to use it. If you want to continue working on the branch in that module, it is a simple matter to merge from the archive first to pick up the changes made while you were disconnected.

Distributed Development

In a distributed development environment, there is no main branch. Instead, each developer maintains their own branch, and pulls changes from other developers’ archives. A few things fall out from this model:

  • To start working on a distributed project, you need to branch off from another developer’s archive. This can be achieved using the same instructions as found in the “disconnected development” section above.
  • In order for other developers to pull changes from your archive, they will need to be able to access it. This isn’t possible if it only exists in your home directory.
  • If you never merge from a particular developer, you don’t even need to know they exist.
  • Conversely, you don’t need to ask for permission to work on a module (however, if you want your changes to appear in the other developers’ archives, you’ll need to ask them to merge from you).

So assuming you’ve branched off an existing developer’s branch of a module, and want other developers to merge your changes. Assuming they can’t access your local computer, it will be necessary to create a mirror of the archive. To make the archive most widely available, you should mirror it to a directory that is published by a web server. The following command will create a mirror of the local archive:

baz make-archive --signed --listing --mirror \

Once the archive is created, you can mirror all the changes in the local archive to the remote one using the following command:

baz archive-mirror

If you always have access to the mirror host, it is possible to set up a hook script that mirrors after every commit. However, if you often make changes while offline you might decide to mirror manually.

Now that the archive has been mirrored, other developers can merge your changes into their working copy using the following command:

baz merge http://hostname/~joe/

(after they’ve used your archive once, they can use the short name for the archive, and it will use the same location as last time).


While Arch allows full distributed development, most projects don’t use it in a fully distributed manner. Often there will be a central archive that is the “official” one, which tarball releases are made from. The exact policies can differ from project to project. Some possible policies are:

  • A core of developers have commit access to an “official” archive, which releases are made from. Developers generally commit directly to this archive (this is the default CVS/Subversion model). External developers follow the distributed development model, and get core developers to merge their changes.
  • As above, but the core developers usually develop their changes on separate branches (usually in their own archives), and only merge them when ready. This is how some projects currently use CVS, but has the benefit of allowing disconnected development.
  • Control of the official archive is managed by arch-pqm. Authorized developers can send merge requests to PQM (using PGP for authentication). When a merge request is received, the branch is merged into the mainline. If there are no conflicts and the test suite runs successfully, the changes are committed.

I’m not sure which model would work best for Gnome. At least initially, one of the first two models would probably be a good choice. If you have good test coverage, PQM can help ensure that the mainline stays buildable, and changes don’t destabilise things.

As has been mentioned elsewhere, regularly updated mirrors of various CVS repositories are being set up at You can find out whether a mirror has been created for a module by looking it up on Launchpad. If a branch exists, you can check it out or branch it by prepending “” to the full branch name (e.g.‌‌gossip--MAIN--0).

SCM Command Line Interface Comparison

With the current discussion on gnome-hackers about whether to switch Gnome over to Subversion, it has been brought up a number of times that people can switch from CVS to Subversion without thinking about it (the implication being that this is not true for Arch). Given the improvements in Bazaar, it isn’t clear that Subversion is the only system that can claim this benefit.

For the sake of comparison, I’m considering the case of a shared repository accessed by multiple developers over SSH. While this doesn’t exploit all the benefits of Arch, it gives a better comparison of the usability of the different tools.


Before using any of CVS, Subversion or Arch, you’ll need a repository. This can be done with the following commands (run on the repository server):

cvs init /cvsroot
svnadmin create --fs-type=fsfs /svnroot
baz make-archive --signed /archives/

(the --signed flag can be omitted if you don’t want to cryptographically sign change sets)

Once the archive is created, you’d need to make sure that everyone has write access to the files, and new files will be created with the appropriate group ownership. This procedure is the same for each system.

Now before users of the arch archive can start using the archive, they will need to tell baz what user ID to associate. Each user only needs to do this once. The email address used should match that on your PGP key, if you’re using a signed archive.

baz my-id "Joe User <>"

Next you’ll want to import some code into the repository. This will be done from one of the client machines, from the source directory:

cvs -d :ext:user@hostname:/cvsroot import modulename vendor-tag release-tag
svn import . svn+ssh://user@hostname/svnroot/modulename/trunk
baz import -a sftp://user@hostname/archives/

In the subversion case, we’re using the standard convention of putting the main branch in a trunk/ subdirectory. In the arch case, you need a three-level module name, so I picked a fairly generic one.

Working with the repository

The first thing a user will want to do is to create a working copy of the module:

cvs -d :ext:user@hostname:/cvsroot get modulename
svn checkout svn+ssh://user@hostname/svnroot/modulename/trunk modulename
baz get sftp://user@hostname/archives/ modulename

The user can then make changes to the working copy, adding new files with the add sub-command, and removing files with rm sub-command. For Subversion there are also mv and cp sub-commands. For Arch, the mv sub-command is supported.

To bring the working copy up to date with the repository, all three systems use the update sub-command. The main difference is that CVS and Subversion will only update the current directory and below, while Arch will update the entire working copy.

If there are any conflicts during the update, you’ll get standard three-way merge conflict markers in all three systems. Unlike CVS, both Subversion and Arch require you to mark each conflict resolved using the resolved sub-command.

To see what changes you have in your working copy, all three systems support a diff command. Again, this works on the full tree in Arch, while only working against a subtree in CVS and Subversion. In all three systems, you can request diffs for individual files by passing the filenames as additional arguments. Unfortunately baz requires you to pass “--” as an argument before the filenames, but hopefully that’ll get fixed in the future.

When it is time to commit the change, all three systems use the commit sub-command. This command also works on a full tree with Arch.

Branching and Merging

Creating a branch is relatively easy in all three systems:

cvs tag foo-anchor . ; cvs tag -b foo .
svn cp . svn+ssh://user@host/svnroot/modulename/branches/foo
baz branch modulename--foo--0

Unlike CVS and Subversion, the baz command will also switch the working copy over to the new branch. By default it will create a branch in the same repository, but can just as easily create a branch in another location.

To switch a working copy between branches, the following commands are used:

cvs update -r foo
svn switch svn+ssh://user@host/svnroot/modulename/branches/foo
baz switch modulename--foo--0

If we switch the working copy back to the trunk, we can merge the changes from the branch you’d do the following:

cvs tag -r foo foo-DATE .; cvs update -j foo-anchor -j foo-DATE .
svn merge -r branch-rev:HEAD svn+ssh://user@host/svnroot/modulename/branches/foo
baz merge modulename--foo--0

This is where Arch’s history sensitive merging starts to shine. Since the working copy retains a record of what changes it is composed of, the merge operation simply pulls over the changes that exist in the branch but not in the working copy — there is no need to tell it what range of changes you want to apply.

To merge more changes from the branch, the CVS and Subversion commands change, while the Arch one remains constant:

cvs tag -r foo foo-DATE .; cvs update -j foo-LAST-DATE -j foo-DATE .
svn merge -r last-merge-rev:HEAD svn+ssh://user@host/svnroot/modulename/branches/foo
baz merge modulename--foo--0


The current Bazaar command line interface isn’t that different from CVS and Subversion (it’s definitely worth a second look if tla scared you off). The main difference is that some of the operations work on the whole working copy rather than a subset by default. In practice, this doesn’t seem to be much of a problem.

The history sensitive merge capabilities would probably be quite useful for Gnome. For example, it would make it trivial to merge bug fixes made on the stable branch to the head branch.

Disconnected development is a natural extension to the branching and merging support mentioned earlier. The main difference is that you’d have to make a local archive, and then create your branch of the code in that archive instead of the main one. The rest is handled the same.

6 January 2005


I’ve put some of the photos from my trip to Mataró, and the short stop over in Japan on the way back. The Mataró set includes a fair number taken around La Sagrida Familia, and the Japan set is mostly of things around the Naritasan temple (I didn’t have enough time to get into Tokyo).


A few months back, I got a second monitor for my computer and configured it in a Xinerama-style setup (I’m actually using the MergedFB feature of the radeon driver, but it looks like Xinerama to X clients). Overall it has been pretty nice, but there are a few things that Gnome could do a bit nicer in the setup:

  • Backgrounds get stretched over both screens. The Ubuntu backgrounds already looked a bit weird at a 5:4 aspect ratio. They look even worse at a 5:2 ratio :-). Ideally the background image would be repeated on each monitor of the virtual screen. Some details are available as bug 147808, but it looks like the fix would be in EelBackground code.
  • Most parts of the desktop treat the monitors as independent (which is good, since most people pick Xinerama over classic X multi-screen so that dragging windows between monitors works, rather than to build video walls), but there is a few bits that don’t. One of the more obvious ones is in Metacity: the alt+tab dialog pops up centred on the monitor where mouse currently resides, but it cycles through all the windows visible on the virtual screen. This is a bit confusing, since it looks like it will be a monitor-local operation based on the position of the dialog (however, if it was monitor-local I’m not sure how you’d switch focus to a window on the other monitor with only the keyboard …).


The new merge command in baz is quite nice. This provides support for merging in ways that tla can’t. One of the limitations of star-merge is that it can get confused if you don’t strictly follow the star topology when merging. That is, you should only merge to/from the person you branched from, and people who branched from you. If siblings merge for instance, it can cause problems with subsequent merges.

The new merge command doesn’t suffer from that problem, and allows you to merge from anyone. Of course, if you break the star topology, people wanting to merge from you will either need to be using Bazaar, or ask for you to merge from them first (so that the star-merge algorithm merges the right changes).

15 December 2004


The conference has been great so far. The PyGTK BoF on the weekend was very productive, and I got to meet Anthony Baxter (who as well as being the Python release manager, wrote a cool VoiP application called Shtoom). There was an announcement of some of the other things Canonical have been working on, which has been reported on in LWN (currently subscriber only) among other places.

Over the weekend, I had a little time to do some tourist-type things in Barcelona. I went to La Sagrada Família. It was a great place to visit, and there was an amazing level of detail in the architecture. You can walk almost to the very top of the cathedral, and see out over the Barcelona skyline (and see various bits of the cathedral not visible from the ground). I’ll have to put my photos up online.


I’ve been using using Bazaar a bit more at work, and it is becoming quite usable, compared to tla. It is a little interesting using daily builds of baz from the 1.1 development branch, where some features appear, get renamed or removed as they get developped, but it has a few more useful features not found in the 1.0 release. From a user point of view, it feels like the command line interface for baz is being designed to be easy to use, while tla‘s feels like they made choices based on what was easy to implement.

I built some Fedora Core 2 i386 builds of the 1.0.1 release, and some 1.1 snapshots that are now up on the Bazaar website in case anyone wants to try them. When I get back home and install FC3 onto my AMD64 box (it only has Ubuntu on at the moment), I’ll do some FC3 x86-64 and i386 builds too.