Wiki Tools

  • Find Page
  • Recent Changes
  • Page History
  • Attachments

Revision 5 as of 2009-02-24 21:20:23

Clear message



Bazaar is a very flexible tool but that flexibility can translate to complexity for new users trying to get started contributing to a project. Shared repositories, lightweight checkouts, bound branches and trees vs no-trees are sweet but it's too much for many new users to digest. We need an easier way for users to bootstrap into a local workspace set up appropriate for the project's size & workflows and the user's planned contribution level.


The best way for a Bazaar user to organize their workspace for a project depends on numerous factors including:

  • user role: project owner vs core developer vs casual contributor
  • workflows: particularly the workflow the project encourages/mandates for making contributions
  • size: large projects have different resource requirements to small ones.

There are at least 4 common ways of organizing one's workspace. For want of better names, let's call them:

  • lightweight checkout
  • standalone tree
  • feature branches
  • switchable sandbox.

Bazaar makes it easy to set up the first two models currently. It ought to make it easy to set up the last 2 models as well.

A brief description of each model follows.

Workspace models

Lightweight checkout

In this model, the working tree is local and the branch is remote. This is the standard model used by CVS and Subversion: it's simple and well understood.

To set up:

  bzr checkout --lightweight URL project
  cd project

To work:

  (make changes)
  bzr commit
  (make changes)
  bzr commit

Note that each commit implicitly publishes the change to everyone else working from that branch. However, you need to be up to date with changes in the remote branch for the commit to succeed. To grab the latest code and merge it with your changes, if any:

  bzr update

Standalone tree

In this model, the working tree & branch are in the one place. Unless a shared repository exists in a higher level directory, the repository is located in that same place as well. This is the default model in Bazaar and it's great for small projects (e.g. a plug-in).

To set up:

  bzr branch URL project
  cd project

To work:

  (make changes)
  bzr commit
  (make changes)
  bzr commit

To publish changes to a central location:

  bzr push [URL]

The URL for push is only required the first time.

If the central location has, in the meantime, received changes from other users, then you'll need to merge those changes into your local branch before you try to push again:

  bzr merge
  (resolve conflicts)
  bzr commit

As an alternative, a (normal) checkout can be used so that a separate publish step in not required. COMMENT: I didn't understand that sentence at all. -kfogel

Feature branches

In this model, there are multiple branches/trees, typically sharing a repository. One branch is kept as a mirror of "trunk" and each unit-of-work (i.e. bug-fix or enhancement) gets its own "feature branch". This model is ideal for most projects, particularly moderately sized ones.

To set up:

  bzr init-repo project
  cd project
  bzr branch URL trunk

To start a feature branch:

  bzr branch trunk featureX
  cd featureX

To work:

  (make changes)
  bzr commit
  (make changes)
  bzr commit

To publish changes to a mailing list for review & approval:

  bzr send

To publish changes to a public branch (that can then be registered as a Launchpad merge request, say):

  bzr push [URL]

As a variation, the trunk can be created as a checkout. If you have commit privileges on trunk, that lets you merge into trunk and the commit of the merge will implicitly publish your change. Alternatively, if the trunk URL is read-only (e.g. a http address), that prevents accidental submission this way - ideal if the project workflow uses an automated gatekeeper like PQM, say.

Local sandbox

This model is very similar to the feature branches model except that the feature branches share a single working tree rather than having one each. This is the default model in git and it's useful for projects with really large trees (> 10000 files say) or for projects with lots of build artifacts (like *.o or *.class files).

To set up:

  bzr init-repo --no-trees project
  cd project
  bzr branch URL trunk
  bzr checkout --lightweight trunk sandbox
  cd sandbox

COMMENT: Hmmm, except that now when you commit to sandbox, it implicitly pushes that to trunk, and that means trunk is no longer a mirror of the upstream URL, right? -kfogel

To start a feature branch:

COMMENT: so below, are we assuming that trunk, when we branch it, is a perfect mirror of some revision of the upstream URL? -kfogel

  bzr branch ../trunk ../featureX
  bzr switch ../featureX

The processes for making changes and submitting them are otherwise identical to those used for feature branches.

Proposed UI enhancements

Here's the proposed steps for setting up a workspace using the feature branches model:

  bzr branch --trunk URL project
  (a shared repository has been created in project with a branch called trunk under there)
  cd project

COMMENT: I love the general idea. But having "--trunk" be the option name is a bit implementationey. Frankly, I wish "bzr branch" would just do something like this by default. However, that would be problematic, for compatibility reasons if nothing else. Maybe "--multi" instead? Any other ideas? -kfogel

Here's the proposed steps for setting up a workspace using the local sandbox model:

  bzr branch --sandbox URL project
  (a shared no-trees repository has been created in project with a branch called trunk and a lightweight checkout called sandbox under there)
  cd project/sandbox

To create workspaces where trunk is a checkout rather than a branch, the checkout command should be used instead, i.e. the checkout command would also gain the --trunk and --sandbox options.

COMMENT: Does the trunk branch ever get bound? (That is, one or both of "bzr bind" and putting a public_branch value in .bzr/branch/config.) -kfogel

The commands beyond the setup - starting a feature branch, making changes and publishing them - can remain the same. As an optional enhancement though, the command for starting a feature branch in the local sandbox model could be simplified to:

  bzr branch --switch ../trunk ../featureX


JohnArbashMeinel has released a bzr-start plugin which, IIUIC, implements "branch --switch" via a new command called "start". "start" feels a bit ambiguous as a name to me so my leaning is towards adding an option to branch (or switch?).

We could add additional options down the track for specifying custom names for the trunk and mirror subdirectories. I don't think this is needed in the initial release. (In fact, standardizing the names may reduce the amount of support projects need to provide new contributors.)

AlexanderBelchenko has suggested that lightweight checkouts should support relative paths to the bound branch. That would make it easier for users who decide to rename or move the project directory.

DanielWatkins has a patch under review adding -r support to the switch command. That will be useful in the local sandbox model.

The bzr-fastimport plugin is a common path for users migrating from git. It ought to gain a --sandbox option compatible with the above scheme. (The other models are already supported by it, though the documentation could make it clearer as to how.)

Implementation notes

I feel these changes belong in the core, though they could be initially delivered by a plugin until consensus was achieved re the UI. A new bzr-quicksetup plugin could add the necessary options or John's bzr-start plugin could be extended to do so.

The --trunk and --sandbox options are probably best implemented by adding new list options (called workspace say) to branch and checkout. The supported values would be:

  • branch: standalone, trunk, sandbox
  • checkout: lightweight, standalone, trunk, sandbox

The default in both cases would be standalone.

There are more than these four models supported by Bazaar. Additional models could be added to these list options later.

Note: --lightweight is currently a boolean flag for checkout so making it a list option value would mean --no-lightweight would no longer work. I don't believe that ought to be an issue if it was documented in the Compatibility Breaks section of NEWS.