cobzr is a wrapper for the bzr command that implements support for git-style co-location of branches onto the same directory. This is achieved by playing with lightweight checkouts and branch locations.
Support for this functionality inside Bazaar itself is already in-progress and will be available in the next release, so you may want to wait a little bit in case you're not in a rush to get this feature.
There's also a plugin 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.
For more details on how the project was born, please check the blog post describing it.
How it works
cobzr definitely falls onto the dubious hack category, rather than being a brilliant design to last for generations. The "cobzr" executable does not integrate into Bazaar as a plugin, for instance. Instead, it works as a wrapper that drives bzr externally. To do that, it introspects the possible command line arguments using "bzr <cmd> --help" calls (it caches the result so that there's almost zero overhead), and then processes the command line. Depending on the command and its arguments, it may do nothing and just pass it through to the real bzr, mutate the arguments and pass it through, or even create an entirely new behavior.
For more details, see Usage and internals below.
If you're using Ubuntu or Debian, the easiest way to install and maintain cobzr up-to-date is by using its PPA:
$ sudo add-apt-repository ppa:gophers/go $ sudo apt-get update $ sudo apt-get install cobzr
Otherwise, you can install cobzr straight from the repository using the Go toolset:
$ go install launchpad.net/cobzr
Once installed, you may want to create a symlink to make its usage more comfortable by having it under the "bzr" name. For example:
$ ln -s /usr/bin/cobzr $HOME/bin/bzr $ export PATH=$HOME/bin:$PATH
This works correctly because cobzr searches for the real bzr by looking in $PATH for the first executable named bzr that is not itself.
Usage and internals
The following is the output of running "cobzr help cobzr" (or "bzr help cobzr", if you're linking to it as described above). In most cases, the cobzr command syntax mimics closely the equivalent git command that implement the given behavior.
Usage: The following extensions to the standard bzr command set are supported. Note that cobzr will only adapt the tree organization once a command requiring multiple branches is executed. In every other case, the tree remains as a normal bzr tree. cobzr help cobzr Show this help message. cobzr branch List current branches. An unconverted tree has a single branch named "master", and when the tree is first converted the initial branch remains as "master". cobzr checkout -b <name> Create a new branch with <name> based on the current one and switch to it. cobzr checkout <name> cobzr switch <name> Switch to branch <name>. cobzr branch <name> Create a new branch with <name> based on the current one, but don't switch to it. cobzr branch <target> [<origin>] Create a new branch <target> based on branch <origin>. Either option may be a branch name or an external branch location. If <origin> isn't provided, the current branch is used. cobzr branch -d <name> Delete branch <name>. Note that right now this is equivalent to git branch -D. In the future, this will check if the branch was merged and prevent deletion otherwise. The -d name was used to avoid teaching people to ignore by default. cobzr branch -m [<old name>] <new name> Move (rename) branch <old name> to <new name>. If <old name> isn't provided, the current branch will be moved. cobzr init <name> Create a new branch with <name>. Will not share any history with other branches. cobzr diff <arg> [<arg>] If any of the parameters to diff is a name that does not match a filename in the current directory, it's taken as a branch name and the requested operation run appropriately. cobzr log <name> Show logs for the given branch. cobzr missing <name> Show unmerged/unpulled revisions between current branch and <name>. cobzr ... Everything else, passthrough to bzr. That includes the above commands in cases where the arguments are a path or URL rather than a name. Internals: The branch organization used by cobzr is very straightforward. Assuming you have a pristine bzr branch under /branch/dir/, once you run a cobzr command that requires multiple branches to exist, the tree will be reorganized as such: branch/dir/ Lightweight checkout of the current branch. branch/dir/.bzr/cobzr Shared repository for all the branches. branch/dir/.bzr/cobzr/<name> Tree-less branch directory for branch <name>.
The source code is available via Bazaar (obviously):
$ bzr branch lp:cobzr
You can report issues in Launchpad:
Gustavo Niemeyer <email@example.com>