<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
<title>Bazaar checkouts, branches and repositories</title>
<link rel="stylesheet" href="../../default.css" type="text/css" />
</head>
<body>
<div class="document" id="bazaar-checkouts-branches-and-repositories">
<h1 class="title">Bazaar checkouts, branches and repositories</h1>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#getting-ready" id="id1" name="id1">Getting ready</a></li>
<li><a class="reference" href="#core-concepts" id="id2" name="id2">Core concepts</a><ul>
<li><a class="reference" href="#checkouts" id="id3" name="id3">Checkouts</a></li>
<li><a class="reference" href="#branches" id="id4" name="id4">Branches</a></li>
<li><a class="reference" href="#repositories" id="id5" name="id5">Repositories</a></li>
</ul>
</li>
<li><a class="reference" href="#sharing-history" id="id6" name="id6">Sharing history</a><ul>
<li><a class="reference" href="#stacked-branches" id="id7" name="id7">Stacked branches</a></li>
<li><a class="reference" href="#shared-repositories" id="id8" name="id8">Shared repositories</a></li>
<li><a class="reference" href="#dependent-branches" id="id9" name="id9">Dependent branches</a></li>
</ul>
</li>
<li><a class="reference" href="#more-tips-tricks" id="id10" name="id10">More tips &amp; tricks</a><ul>
<li><a class="reference" href="#sharing-working-files" id="id11" name="id11">Sharing working files</a></li>
<li><a class="reference" href="#heavyweight-checkouts" id="id12" name="id12">Heavyweight checkouts</a></li>
<li><a class="reference" href="#looms" id="id13" name="id13">Looms</a></li>
</ul>
</li>
<li><a class="reference" href="#learning-more" id="id14" name="id14">Learning more</a></li>
</ul>
</div>
<p>Bazaar lets you organise your work to be most efficient for the things you
want to get done. If you just want to make a quick change to code on an
existing project, you can do that. If you want to work on a feature which
will require multiple revisions over a period of time, while you are online
and offline, you can do that. If you want to keep all the changes from
different pieces of work separate, you can do that, and if you want to share
historical data or working files across multiple lines of development,
you can do that too.</p>
<p>In a nutshell, Bazaar puts <em>you</em> in control, adapting to how you want to work.
That may sound complicated, but it isn't. This tutorial explains what you
need to know to make the most of the core features at the core of Bazaar's
adaptable approach: checkouts, branches and repositories.</p>
<div class="section">
<h1><a class="toc-backref" href="#id1" id="getting-ready" name="getting-ready">Getting ready</a></h1>
<p>You should be able to learn everything you need just by reading this
tutorial. If you want to try the examples in action, you will need Bazaar
1.13 or later, and you need to join the bzr-explorers team at:</p>
<pre class="literal-block">
https://launchpad.net/~bzr-explorers/+join
</pre>
<p>You also want to make sure that you have setup Bazaar to talk to Launchpad:</p>
<pre class="literal-block">
$ bzr lp-login
</pre>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id2" id="core-concepts" name="core-concepts">Core concepts</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id3" id="checkouts" name="checkouts">Checkouts</a></h2>
<p><em>&quot;Quick fixes to code that lives somewhere else.&quot;</em></p>
<p>Imagine that there is some code out there somewhere that you want to change,
and for which you have permission to make the change directly. For example,
someone has setup a Bazaar server and is working on a project, they showed
you the code and you saw a quick little fix. They've given you permission to
edit that code directly.</p>
<p>You don't want all the history, you don't want to have lots of local
revisions before you make your changes in the master copy of that code. You
just want to make the changes directly.</p>
<p>You want a checkout.</p>
<p>A checkout is very similar to the way CVS or Subversion (SVN) work. You just
ask for a copy of the code as it currently stands, you make changes to that
code, and then you <em>commit</em> the changes. And your committed change is
instantly available to everyone else who is looking at that pile of code.
Easy.</p>
<pre class="literal-block">
$ bzr checkout lp:~bzr-explorers/gnuhello/test
</pre>
<p>Translation: <em>Please checkout the 'test' branch of GNU Hello from the
bzr-explorers team in Launchpad.</em></p>
<p>Of course, you don't have to use Launchpad. The URL in question can be any
URL to any Bazaar server or branch, using http, sftp or bzr+ssh as a transport.
But this makes a nice, easy example.</p>
<p>You should now have a directory called <tt class="docutils literal"><span class="pre">test</span></tt>, and inside that directory is
the checkout - all the latest files for <tt class="docutils literal"><span class="pre">gnuhello</span></tt> at that location.</p>
<pre class="literal-block">
$ cd test
$ ls
...
$ bzr status
(nothing to see yet!)
</pre>
<p>Now, the thing you need to understand is that this set of files is linked
directly to the &quot;master&quot; copy over at Launchpad. So, if you commit changes
here, those changes are committed immediately to the master server. And the
next person who checks out from <tt class="docutils literal"><span class="pre">lp:~bzr-explorers/gnuhello/test</span></tt> will see
those changes.</p>
<p>Go ahead and edit one of the files (README if you're looking for attention)
and then:</p>
<pre class="literal-block">
$ bzr status
modified:
  README
$ bzr commit --message=&quot;Updated README&quot;
...
</pre>
<p>If that all looks like it went smoothly, then you have just made your
changes. If you're done, you can just delete the directory.</p>
<p>Advantages of checkouts:</p>
<ul class="simple">
<li>Quick and easy. No mess no fuss.</li>
<li>All the history is still on the other side, so the local files are just
the size of the <em>working tree</em>.</li>
</ul>
<p>Disadvantages of checkouts:</p>
<ul class="simple">
<li>Tethered operation. As the code in question is usually over on another
server, each commit has to go over the network. It therefore feels a
little slower than committing locally. And if you get on a plane
and don't have Internet access, you can't commit.</li>
<li>Every commit changes the master. Sometimes it's nice to be able to
commit frequently work that is incomplete but has reached a natural
checkpoint. With a checkout, your change will update the master code,
and everyone else working from that master will have to deal with that
change, for better or worse.</li>
</ul>
<p>There's one more important thing to know about using checkouts. Since your
files are connected to the master server, and other people might make
changes there after you check them out, you may find yourself being told
that you can't commit your changes because someone else has changed the
master. To bring the newest work from the master into your checkout, run:</p>
<pre class="literal-block">
bzr update
</pre>
<p>You may need to resolve conflicts if those changes collide with the
changes you are making, but then you will be able to commit.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id4" id="branches" name="branches">Branches</a></h2>
<p><em>&quot;A new line of development.&quot;</em></p>
<p>So, what if you want to make larger changes? You might take a couple of
commits to get them right? Or you may want to take <em>snapshots of progress</em>
by committing locally, not publishing those revisions till you are ready
or till you have net access again?</p>
<p>You need a branch!</p>
<p>A branch is just like a checkout, except that it brings over all of the
history as well as the current versions of the files you checked out. And
you can add revisions to the branch by committing, without affecting the
original place you branched from. Of course, you can send your changes there
when you're ready, but until then you are completely independent.</p>
<pre class="literal-block">
$ bzr branch lp:gnuhello my_branch
</pre>
<p>You should now have your very own branch of <tt class="docutils literal"><span class="pre">gnuhello</span></tt>, in a directory
called <tt class="docutils literal"><span class="pre">my_branch</span></tt>. Take a look at it.</p>
<p>At first, it looks just like a checkout. It has a full <em>working tree</em> of the
latest version of all the files you just fetched from Launchpad.</p>
<p>But you may have noticed that it took a little longer for the branch to
happen than for the checkout to happen, previously. That's because a branch
operation brings over <strong>all</strong> the history of the code you are branching. That
means you have your own copy of all of that history, here, in the branch.
The upside of that is that you can extend the branch, adding more history
locally, without ever telling anyone else.</p>
<p>The visible files you will see in <tt class="docutils literal"><span class="pre">my_branch</span></tt> are the working tree, the latest
versions of all the files in the branch. It looks just like a checkout. In
fact, if you don't look too closely, it <em>is</em> a checkout. The branch itself is
tucked away inside the directory <tt class="docutils literal"><span class="pre">my_branch/.bzr</span></tt> and is probably invisible to
you unless you go looking for it. All the working tree files - the code you
are looking at - is really a checkout of that local branch! But don't let
that thought bake your noodle.</p>
<p>Try modifying a few files. This time, when you commit, you won't be sending
your changes to Launchpad. You'll just be committing to your local branch,
extending the local history. So you'll notice that commit feels immediate -
and it works even if you're disconnected. That's because the revision you
commit is being stored inside that <tt class="docutils literal"><span class="pre">my_branch/.bzr</span></tt> directory, not sent over
the network.</p>
<p>Using this model, you won't have to use <tt class="docutils literal"><span class="pre">bzr</span> <span class="pre">update</span></tt>, because no changes can
creep into <em>your</em> branch unless you explicitly let someone else commit into
it. Of course, when you want to send all your changes back to the master,
you may need to resolve conflicts. It's best to <em>merge</em> from there and resolve
them locally, then push up your changes, or ask them to merge from you if
you can't commit to the master.</p>
<p>If you check the size of the directory, perhaps using <tt class="docutils literal"><span class="pre">du</span> <span class="pre">-csh</span></tt>, you'll notice
that the <tt class="docutils literal"><span class="pre">my_branch</span></tt> directory is much bigger than the <tt class="docutils literal"><span class="pre">test</span></tt> checkout.
That's because of all the history data you've brought down.</p>
<p>Advantages of branches:</p>
<ul class="simple">
<li>Everything is local, so it's fast and you can work just as well online
as offline.</li>
<li>Each branch is completely isolated from the next one. It's
self-contained, with the working tree there and the history data all
hidden away inside the <tt class="docutils literal"><span class="pre">.bzr</span></tt> directory. Until you show someone else that
directory, the work you do there is completely confidential.</li>
</ul>
<p>Disadvantages of branches:</p>
<ul class="simple">
<li>You have a copy of history for every branch. If you have many branches
for the same project, the space can add up, and it can slow you down a
little to move that data around all the time.</li>
</ul>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id5" id="repositories" name="repositories">Repositories</a></h2>
<p><em>&quot;A store of history.&quot;</em></p>
<p>Right, now you know about checkouts and branches. Branches are awesome, and
if your project is not huge, that's all you really need. Don't bother with
anything else. But if carrying all the history of every commit ever merged
with each of your branches becomes a pain, you can organise things so that
all the history for multiple branches is stored just <strong>once</strong>. Then the
branch metadata is tiny - it's just a file which says &quot;these pieces of
history make up this branch&quot;. And of course, a branch can have a working tree
in it too, the size of a normal checkout.</p>
<p>The <em>store of history</em> is called the repository, and in the previous
examples Bazaar took care of making the repository and updating it in the
right place. For a checkout, the repository is in the master location that
you checked out. For a branch, Bazaar created a repository locally (it's
hidden away inside <tt class="docutils literal"><span class="pre">my_branch/.bzr/repository/</span></tt>) and copied all the history
from your source location into that local repository. It's all that copying
which made each branch larger than the checkout.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id6" id="sharing-history" name="sharing-history">Sharing history</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id7" id="stacked-branches" name="stacked-branches">Stacked branches</a></h2>
<p>Wouldn't it be neat if you could have a branch that only stored new commits
and referred back to the original branch for earlier history? With Bazaar,
you can. In fact, this approach works really nicely with a commonly used
distributed version control model: <em>feature branching</em>.</p>
<p>The feature branching model works like this:</p>
<ol class="arabic simple">
<li>Create a branch which you keep as a mirror of the project trunk.</li>
<li>Create new branches from this mirror for each separate fix or enhancement.</li>
</ol>
<p>By separating changes out like this, each change can evolve at its natural
rate. For example, you may make a fix and send it off to a peer for review
and comments. While you're waiting on that feedback, you can work on another
fix or enhancement. When you get the feedback you're waiting on, make the
agreed changes to the feature branch and, following project policies, either
merge it yourself to trunk or ask someone with the required permissions to do
so.</p>
<p>Creating the trunk branch to use as a mirror is simple:</p>
<pre class="literal-block">
mkdir projectX
cd projectX
bzr branch URL trunk
</pre>
<p>Stacking a feature branch on this is almost as easy:</p>
<pre class="literal-block">
bzr branch --stacked trunk fix-abc
</pre>
<p>After <tt class="docutils literal"><span class="pre">fix-abc</span></tt> is merged into the upstream trunk, the directory holding
that branch can safely be deleted. The commits from that branch will
appear as <em>merged revisions</em> in the log of <tt class="docutils literal"><span class="pre">trunk</span></tt> next time you refresh
your mirror branch.</p>
<p>By the way, stacked branches are awesome when creating experimental branches
- called <em>spikes</em> in some Agile methods like XP - to try out ideas. By using
a stacked branch, deleting the branch directory after you're done will remove
any associated commits. And that's OK - the primary value of an experimental
branch is the things it teaches you.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id8" id="shared-repositories" name="shared-repositories">Shared repositories</a></h2>
<p>Stacked branches are really neat but there are times when you need something
even smarter. While a stacked branch avoids making an unnecessary full
copy of history for a feature branch, if you grab multiple branches from
Launchpad or another hosting site, each branch will get it's own unique
repository wth it's own full copy of history. What's really needed is a
central repository that intelligently shares history when it can. Enter
<em>shared repositories</em>.</p>
<p>A shared repository is simply a parent directory that has been explicitly
created as the place to store history. Branches created as subdirectories
(at any level) within a shared repository detect it and place their
revisions there. No further effort is required.</p>
<p>Once again, shared repositories play really well with the feature branching
model. Here's the typical recipe for using a shared repository:</p>
<pre class="literal-block">
bzr init-repo projectX
cd projectX
bzr branch URL trunk
</pre>
<p>Note that this is almost identical to the recipe described previously when
explaining stacked branches. This time though, we're creating the top level
directory via <tt class="docutils literal"><span class="pre">bzr</span> <span class="pre">init-repo</span></tt> rather than <tt class="docutils literal"><span class="pre">mkdir</span></tt>. And just like before,
you can kick off a feature branch using the recipe below:</p>
<pre class="literal-block">
bzr branch --stacked trunk fix-abc
</pre>
<p>In this case, the <tt class="docutils literal"><span class="pre">--stacked</span></tt> option isn't strictly required but it's still
a good idea anyway for all the reasons previously described, e.g. deleting
an unwanted branch will throw away the asociated commits. If <tt class="docutils literal"><span class="pre">--stacked</span></tt>
isn't given, those commits will be taking a small amount of space in
the shared repository.</p>
<p>By the way, most Bazaar veterans use shared repositories all the time,
typically one per project. You can have just one if that makes you happy -
and all revisions from all projects will be stored there! One per project
is a nice, simple guideline though and works a treat for most users.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id9" id="dependent-branches" name="dependent-branches">Dependent branches</a></h2>
<p><strong>This is a new proposed feature. Please consider the idea and send
your feedback to the mailing list.</strong></p>
<p>Another way to get the benefits of a branch without all the local
history, is just to use the repository of the source you branched from. Of
course, you need to be able to write to that branch location! Your revisions
will be sent to the OTHER repository, but they don't change the &quot;tip&quot; of
that branch, they just slip in alongside all the other bits of history
there. The branch on the other side isn't changed at all, it just gets a bit
more data in the repository. That sometimes confuses people, so here's a
good way to think about it. The repository is like a disk. You can write
lots of files to the disk. The branch itself is like a single file on the
disk. You can write the data for other branches onto the disk, without
changing the branch file there at all. Hope that helps!</p>
<p>So, go ahead and try it. This will work if you have bzr 1.15 or later and it
assumes that you still have the previously created branch in my_branch.</p>
<pre class="literal-block">
$ bzr branch --shared-repo my_branch new_branch
</pre>
<p>Take a look inside new_branch. It looks like a branch, acts like a branch
(commits there don't change the tip of the branch in my_branch) but in terms
of size, it doesn't have all the history that was in my_branch. Because all
that history is still there! And if you commit into new_branch, the branch
is updated but the new history gets written to the OTHER repository, the one
in <tt class="docutils literal"><span class="pre">my_branch/.bzr/repository</span></tt>.</p>
<p>So, this is a neat way to have a <em>main branch</em>, where you keep all the
history, and one or more other branches which are just convenient places to
work on a series of commits. It works best if all of those branches are
local, and not on the network.</p>
<p>You can also be more explicit than this. You can have a repository somewhere
else altogether, and you can make a branch that uses THAT repository. Try
this, in the top-level directory, above new_branch and my_branch:</p>
<pre class="literal-block">
$ bzr init-repo shared-store
$ bzr branch --shared-repo=shared-store my_branch small_branch
</pre>
<p>Essentially, this has made a new branch in small_branch, and it's configured
to stick all the data from that branch into the repository that's living
in shared-store. You can make as many branches as you like, and stick all
the data from them into shared-store. Nifty. But don't accidentally delete
shared-store!</p>
<p>Advantages of dependent branches:</p>
<ul class="simple">
<li>You have all the independence of branches (commits only affect the branch
you are working on) but you also have the space advantage of a checkout,
since all the history for multiple branches can be in the same shared
repository.</li>
</ul>
<p>Disadvantages of dependent branches:</p>
<ul class="simple">
<li>Deleting the shared repository accidentally really hurts.</li>
<li>You probably want to keep all the branches that share a repository on the
same machine. That way you never have to worry about when you are online
or offline.</li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id10" id="more-tips-tricks" name="more-tips-tricks">More tips &amp; tricks</a></h1>
<p>There are quite a few other tricks and tips, but the above is all you really
need to know to look like a champion with Bazaar. If you are interested,
here's a sample of some advanced setups Bazaar can support.</p>
<div class="section">
<h2><a class="toc-backref" href="#id11" id="sharing-working-files" name="sharing-working-files">Sharing working files</a></h2>
<p>You can <em>switch</em> a working tree between branches, very easily. So, if
you have three branches, you can create a checkout of one of them, do some
work, commit, then <tt class="docutils literal"><span class="pre">bzr</span> <span class="pre">switch</span></tt> to the next branch to do some work there.</p>
<p>If you like working this way, you can avoid having a working tree per branch
and use just the one working tree as the place to get stuff done. To do this,
simply put your branches in a treeless, shared repository.</p>
<p>Putting the pieces together, here's the recipe for sharing a working tree
across a set of (treeless) branches:</p>
<pre class="literal-block">
bzr init-repo --no-trees projectX
cd projectX
bzr branch URL trunk
bzr checkout trunk work
cd work
</pre>
<p>To create a new branch to work on a bug fix, say:</p>
<pre class="literal-block">
bzr branch --stacked ../trunk ../fix-abc
bzr switch ../fix-abc
</pre>
<p>And away you go!</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id12" id="heavyweight-checkouts" name="heavyweight-checkouts">Heavyweight checkouts</a></h2>
<p>If you want the lockstep behaviour of a checkout together with the full
local history of a branch, create a <em>heavyweight</em> checkout. These are
actually pretty commonly used, particularly as the mirror branch in
the feature branching model. For example:</p>
<pre class="literal-block">
bzr init-repo projectX
cd projectX
bzr checkout --heavyweight URL trunk
</pre>
<p>After creating and getting a feature brach ready to land like this:</p>
<pre class="literal-block">
bzr branch --stacked trunk fix-abc
cd fix-abc
(hack, hack, hack)
bzr commit --message &quot;fix abc&quot;
</pre>
<p>you can merge that change into the upstream trunk as simply as this:</p>
<pre class="literal-block">
cd ../trunk
bzr merge ../fix-abc
bzr commit --message &quot;merge fix for abc&quot;
</pre>
<p>Sweet.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id13" id="looms" name="looms">Looms</a></h2>
<p>If you're trying to work on a single feature that depends on several
simultaneously developing threads of work, look into <em>looms</em>. Looms
let you manage a stack of related changes, either separately or as a
whole.</p>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id14" id="learning-more" name="learning-more">Learning more</a></h1>
<p>We hope you've found this tutorial useful and are now ready to make
Bazaar work the way you want to. If you have further questions,
please check the rest of the documentation. If you can't find what
you're looking for, or have ideas on how we can make the documentation
better, please contact us via the mailing list (<a class="reference" href="mailto:bazaar&#64;lists.canonical.com">bazaar&#64;lists.canonical.com</a>)
or IRC channel (#bzr on irc.freenode.net)!</p>
</div>
</div>
</body>
</html>