Centralized Workflow Tutorial¶
Overview¶
This document describes a possible workflow for using Breezy. That of using Breezy, the distributed version control system, in a centralized manner. Breezy is designed to be very flexible and allows several different workflows, from fully decentralized to mostly centralized. The workflow used here is meant to ease a new user into more advanced usage of Breezy, and allow them to work in a mix of centralized and decentralized operations.
In general, this document is meant for users coming from a background of centralized version control systems such as CVS or subversion. It is common in work settings to have a single central server hosting the codebase, with several people working on this codebase, keeping their work in sync. This workflow is also applicable to a single developer working on several different machines.
Initial Setup¶
These are some reasonably simple steps to setup Breezy 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 or unique, it will be used in log messages and annotations, so it is better to have something real.
% brz whoami "John Doe <jdoe@organization.com>"
Setting up a local Repository¶
Breezy 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 related 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 let’s set up a Shared Repository in our home directory, thus all branches we create underneath will share their history storage.
% brz init-shared-repo --trees ~
Setting up a remote Repository¶
Many times you want a location where data is stored separately 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. Since 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 to be lost.
So let’s set up a shared location for our project on a remote machine
called centralhost
. Again, we will use a
Shared Repository to optimize disk usage.
% brz init-shared-repo --no-trees brz+ssh://centralhost/srv/brz/
You can think of this step as similar to setting up a new cvsroot, or
subversion repository. The --no-trees
option tells brz to not
populate the directory with a working tree. This is appropriate,
since no one will be making changes directly in the branches within
the central repository.
Here we’re using a brz+ssh
URL, which means to use Breezy’s own
protocol on top of the SSH secure shell. See the Administrator Guide for
information about setting up a brz+ssh server.
Migrating an existing project to Breezy¶
Now that we have a repository, let’s create a versioned project. Most of the time, you will already have some code that you are working with, that you now want to version using Breezy. If the code was originally in source control, there are many ways to convert the project to Breezy without losing any history. However, this is outside the scope of this document. See Tracking Upstream for some possibilities (section “Converting and keeping history”).
Developer 1: Creating the first revision¶
So first, we want to create a branch in our remote Repository, where we want to host the project. Let’s assume we have a project named “sigil” that we want to put under version control.
% brz init brz+ssh://centralhost/srv/brz/sigil
This can be thought of as the “HEAD” branch in CVS terms, or as the “trunk”
in Subversion terms. We will call this the dev
branch.
I prefer working in a subdirectory of my home directory to avoid collisions with all the other files that end up there. 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
% brz checkout brz+ssh://centralhost/srv/brz/sigil dev
% cd dev
% cp -ar ~/sigil/* .
% brz add
% brz commit -m "Initial import of Sigil"
In the previous section, we created an empty branch (the /sigil
branch) on centralhost
, and then checkout out this empty branch
onto our workstation to add files from our existing project. There
are many ways to set up your working directory, but the steps above
make it easy to handle working with feature/bugfix branches. And one
of the strong points of Breezy is how well it works with branches.
At this point, because you have a ‘checkout’ of the remote branch, any
commits you make in ~/work/sigil/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 would just checkout that branch. They should still follow Setting User Email and Setting up a local Repository.
To get a copy of the current development tree:
% cd ~/work/sigil
% brz checkout brz+ssh://centralhost/srv/brz/sigil dev
Now that two people both have a checkout of
brz+ssh://centralhost/srv/brz/sigil
, there will be times when one of
the checkouts will be out of date with the current version.
At commit time, Breezy will inform the user of this and prevent them from
committing. To get up to date, use brz update
to update the
tree with the remote changes. This may require resolving conflicts if the
same files have been modified.
Developing on separate branches¶
So far everyone is working and committing their changes into the same branch. This means that everyone needs to update fairly regularly and deal with other people’s changes. Also, if one person commits something that breaks the codebase, then upon syncing, everyone will get the problem.
Usually, it is better to do development on different 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. Breezy tracks 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 on
centralhost
, and track it locally.
% cd ~/work/sigil
% brz branch brz+ssh://centralhost/srv/brz/sigil \
brz+ssh://centralhost/srv/brz/sigil/doodle-fixes
% brz checkout brz+ssh://centralhost/srv/brz/sigil/doodle-fixes doodle-fixes
% cd doodle-fixes
We now have a place to make any fixes we need to doodle
. And we would
not interrupt people who are working on other parts of the code. Because
we have a checkout, any commits made in the ~/work/sigil/doodle-fixes/
will also show up on centralhost
. [1] It is also
possible to have two developers collaborate on one of these branches, just
like they would have collaborated on the dev
branch.
Merging changes back¶
When it is decided that some of the changes in doodle-fixes
are ready
to be merged into the main branch, simply do:
% cd ~/work/sigil/dev
% brz merge ../doodle-fixes
Now the changes are available in the dev
branch, but they have not
been committed yet. This is the time when you want to review the final
changes, and double check the code to make sure it compiles cleanly and
passes the test suite. The commands brz status
and brz diff
are
good tools to use here. Also, this is the time to resolve any conflicts.
Breezy will prevent you from committing until you have resolved these
conflicts. That way you don’t accidentally commit the conflict markers.
The command brz status
will show the conflicts along with the other
changes, or you can use brz conflicts
to just list conflicts. Use
brz resolve file/name
or brz resolve --all
once conflicts have
been handled. [2] If you have a conflict that is particularly
difficult to solve you may want to use the brz remerge
command. It
will let you try different merge algorithms, as well as let you see the
original source lines (--show-base
).
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:
% brz branch brz+ssh://centralhost/srv/brz/sigil \
brz+ssh://centralhost/srv/brz/sigil/user-a
% brz branch brz+ssh://centralhost/srv/brz/sigil \
brz+ssh://centralhost/srv/brz/sigil/user-b
This gives each developer their own branch to work on. And, they can easily create a new feature branch for themselves:
% brz branch brz+ssh://centralhost/srv/brz/sigil/user-a \
brz+ssh://centralhost/srv/brz/sigil/user-a/feature
% cd ~/work/sigil
% brz checkout brz+ssh://centralhost/srv/brz/sigil/user-a/feature myfeature