Centralized Workflow

Overview

This document describes some basic workflow for using Bazaar. This doesn't try to explain why every step is done, but more gives recommendations about what is considered a good way to work with Bazaar. Bazaar is designed to be very flexible in workflows, from fully decentralized to mostly centralized. The practices here are meant to help ease the user into more advanced usage of Bazaar, and allowing them to work in a mix of centralized and decentralized operation.

In general, this document is meant for people in a work setting. Where several people are working on the same codebase, and want to work with eachother and keep in sync. However, this workflow is also applicable to a single developer, who might work on several machines, and wants to keep in sync with themselves.

Initial Setup

These are some reasonably simple steps to setup Bazaar so that it works well for you.

Setting User Email

Your user identity is stored with each commit. While this doesn't have to be accurate, unique, or anything else, it will be used in log messages an annotations, so it is nice to have something real.:

% bzr whoami "John Doe <jdoe@organization.com>"

Setting up a local Repository

Bazaar branches generally copy the history information around with them, which is part of how you can work in a fully decentralized manner. As an optimization, it is possible for branches to combine their storage needs, so that you do not need to copy around all of this history information whenever you create a new branch.

The best way to do this is to create a Shared Repository. In general, branches will share their storage if they exist in a subdirectory of a Shared Repository. So lets setup a Shared Repository in our home directory, thus all branches we create underneath will share their history storage.:

% bzr init-repo --trees ~

Setting up a remote Repository

Many times you want a location where data is stored separate from where you do your work. This workflow is required by centralized systems (CVS/SVN). Usually they are on separate machines, but not always. This is actually a pretty good setup, especially in a work environment. Because it ensures a central location where data can be backed up, and means that if something happens to a developer's machine, no committed work has been lost.

So lets set up a shared location for our project. Again, we will use a Shared Repository to optimize disk usage.:

% bzr init-repo --no-trees sftp://centralhost/srv/bzr/

You can think of this step as similar to setting up a new cvsroot, or subversion repository (only obviously it is a little bit simpler).

Starting to version an existing project

Now that we have a repository, lets get going with a new project. Most of the time, you will already have some code that you started working with, that you now want to version using Bazaar. If the code was originally in source control, there are many ways to convert the project to Bazaar without losing any history. However, this is outside of the scope of this document. See XXXReferenceConversionOfHistory_.

Developer 1: Creating the first revision

So first, we want to create a branch in our remote Repository, where we will want to host the project. Let's assume we have a project named "sigil" that we want to start versioning, and create an empty branch:

% bzr init sftp://centralhost/srv/bzr/sigil

This can be thought of as the "HEAD" branch in CVS terms, or as the "trunk" in Subversion terms. We typically call this the dev branch.

I prefer working in a subdirectory of $HOME to avoid collisions with all the other stuff that ends up in $HOME. Also, we will want a project directory where we can hold all of the different branches we end up working on:

% cd ~
% mkdir work
% cd work
% mkdir sigil
% cd sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil dev
% cd dev
% cp -ar ~/sigil/* .
% bzr add
% bzr commit -m "Initial import of Sigil"

There are many ways to setup your working directory, but the above way will makes it easy to handle working with feature/bugfix branches. And one of the strong points of Bazaar is how well it works with branches.

At this point, because you have a 'checkout' of the remote branch, any commits you make in dev/ will automatically be saved both locally, and on centralhost.

Developer N: Getting a working copy of the project

Since the first developer did all of the work of creating the project, all other developers can just get a checkout of that branch. They should still follow Setting User Email and Setting up a local Repository.

Then to get a copy of the current tip:

% cd ~/work/sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil dev

Now that two people both have a checkout of sftp://centralhost/srv/bzr/sigil, there will be times when one of them is out of date with the current version. Bazaar will inform the user of this and prevent them from committing. To get up to date use bzr update, which will update the tree with the remote changes. This may require resolving conflicts, in the case that the same files have been modified.

Developing on separate branches

So far everyone is working and committing their changes into the same branch. Which means that everyone needs to update fairly regularly, and deal with other people's changes. Also, if one person commits something which breaks the codebase, then everyone has to deal with it.

Usually, it is better to do development on individual branches, and then integrate those back into the main branch, once they are stable. This is one of the biggest changes from working with CVS/SVN. They both allow you to work on separate branches, but their merging algorithms are fairly weak, so it is difficult to keep things synchronized. Bazaar merges track what has already been merged, and can even apply changes to files that have been renamed.

Creating and working on a new branch

We want to keep our changes available for other people, even if they aren't quite complete yet. So we will create a new public branch, and track it locally.:

% cd ~/work/sigil
% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/doodle-fixes
% bzr checkout sftp://centralhost/srv/bzr/sigil/doodle-fixes doodle-fixes
% cd doodle-fixes

We now have a place to make any fixes to doodles that we need. And we won't interrupt people who are working on other parts of the code. Because we have a checkout, any commits made in the doodle-fixes/ will also show up on centralhost. [#nestedbranches_] It is also completely possible to have 2 developers collaborate on one of these branches, just like they would have collaborated on the dev branch.[#cbranch]_

[1]When using lots of independent branches, having to retype the full URL all the time takes a lot of typing. We are looking into various methods to help with this, such as branch aliases, etc. For now, though, the bzrtools plugin provides the bzr cbranch command. Which is designed to take a base branch, create a new public branch, and create a checkout of that branch, all with much less typing. Configuring cbranch is outside the scope of this document, but the final commands look like bzr cbranch dev my-feature-branch
[2]It may look odd to have a branch in a subdirectory of another branch. However, this is just fine, and you can think of it as a heirarchial namespace. Where the nested branch is derived from the outer branch.

Merging changes back

When it is decided that some of the changes in doodle-fixes is ready to be merged into the main tree, simply do:

% cd ~/work/sigil/dev
% bzr merge ../doodle-fixes

Now the changes are available in the dev branch, but they haven't been committed yet. This is the time when you want to review the final changes, and make sure they are what you want. bzr status and bzr diff are good tools to use here. Also, there may be some conflicts in files, if there were changes made to the same file. Bazaar will prevent you from committing until you have resolved these conflicts. That way you don't accidentally commit the conflict markers. bzr status will show the conflicts along with the other changes, or you can use bzr conflicts to just list conflicts. Use bzr resolve file/name or bzr resolve --all once conflicts have been handled.[#resolve]_ If you have a conflict that is particularly difficult to solve you may want to use the bzr remerge command. It will let you try different merge algorithms, as well as let you see the original source lines (--show-base).

[3]Some systems make you resolve conflicts as part of the merge process. We have found that it is usually easier to resolve conflicts when you have the view of the entire tree, rather than just a single file. It gives you much more context, and also lets you run tests as you resolve the problems.

Recommended Branching

One very common way to handle all of these branches is to give each developer their own branch, and their own place to work in the central location. This can be done with:

% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/user-a
% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/user-b

This gives each developer their own branch to work on. And, they can easily create a new feature branch for themselves with just[#cbranch]_:

% bzr branch sftp://centralhost/srv/bzr/sigil/user-a \
             sftp://centralhost/srv/bzr/sigil/user-a/feature
% cd ~/work/sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil/user-a/feature myfeature

Glossary

Shared Repository

Bazaar has the concept of a Shared Repository. This is similar to the concept of other RCS's repository. Such as in Subversion, where you have a remote repository, which is where all of the history is stored, and locally you don't have any history information, only a checkout of the working tree files. Note that "Shared" in this context means shared between branches. It may be shared between people, but standalone branches can also be shared between people.

In Bazaar terms, a Shared Repository is a location where multiple branches can share their revision history information. Because Bazaar wants to support decentralized workflows, it is possible for every branch to maintain its own revision history information. But this is often inefficient, since often branches share history, and they might as well share the storage as well.

Docutils System Messages

System Message: ERROR/3 (doc/centralized_workflow.txt, line 83); backlink

Unknown target name: "xxxreferenceconversionofhistory".