ddaa bbloggs: /bzr/repository-branch-tree

Repositories, branches and trees

These are words you are sure to find in the documentation of any version control system. In CVS, Subversion or GNU Arch they are very distinct objects. In git and Mercurial, they are conceptually distinct but are represented by a single object on disk.

In Bazaar, you can pick and choose, as separate or as conflated as you wish. This allows it to support configurations familiar to CVS and Subversion users, as well as the convenience of all-in-one trees.

In the simplest case, bzr init creates a standalone tree. A tree that contains a repository and a single branch, like this:

my-tree
 | .bzr
 |  | repository
 |  | branch
 |  ` checkout
 | hello.c
 ` README

You can also create a shared repository for multiple branches to use the same storage. This save disk space and data copying. This is done with bzr init-repository. And that looks like this:

my-repo
 `.bzr
   ` repository

Then you can start creating branches in the repository. Using commands like bzr branch my-tree my-repo/my-branch:

my-repo
 | .bzr
 |  ` repository
 ` my-branch
    | .bzr
    ` branch

Note how my-branch neither contains a repository nor a working tree [1]. Other branches created in my-repo will use the same common storage.

[1] At least in bzr-0.13. In earlier versions, init-repository created by default a repository where the branches had trees. This behaviour was provided by init-repository --no-trees. At least up to bzr-0.13. Developers are considering to change the default of init-repository to create a repository where the branches have trees.

To extract a tree from the repository, use a command like bzr checkout --lightweight my-repo/my-branch my-light. That would give you a so-called lightweight checkout:

my-light
 | .bzr
 |  | branch (reference)
 |  ` checkout
 | hello.c
 ` README

The branch in a lightweight checkout is a special branch reference that contains no actual data, just the URL of the actual branch in the repository.

Note that, if you are so inclined, you can create a lightweight checkout from standalone tree.

If you want to keep all your trees handy, and still benefit from the disk space and performance gains of using a repository, you can create the the repository using bzr init-repository --trees. Creating a branch in this repository would yield this result:

my-repo
 | .bzr
 | ` repository
 ` my-branch
    | .bzr
    |  | branch
    |  ` checkout
    | hello.c
    ` README

Note that you can also achieve this result by running bzr checkout (no further argument) in a branch that does not already have a tree. Conversely, you can remove the tree from a branch using bzr remove-tree.

So which combinations did we see?

repo branch tree  
yes yes yes standalone tree
yes no no shared repository
no yes no repository branch
no no yes lightweight checkout
no yes yes repository checkout

Are other combinations meaningful?

repo branch tree  
yes yes no standalone branch
no no no pure branch reference
yes no yes ???

Standalone branches are self-contained branches without a tree. They are created by bzr push when the push destination is on a remote URL (like sftp, ftp, http). The bzr push command does not update working trees at remote URLs to improve performance and to prevent the occurence of merge conflicts. So it may as well not create a tree in the first place..

Pure branch references are exotic, but they are actually useful. Launchpad uses them to implement a redirection mechanism.

The last combination is a repository, without a branch, with a tree. I do not think it would be really useful, but I can imagine how it would work. That would be a lightweight checkout at the root of a shared repository.

10 Dec. 2006 Repositories, branches and trees (2 comments)

Posted by James Henstridge at Mon Dec 4 05:34:01 2006

A lightweight checkout does contain a branch of a kind: a branch reference.  It's a bit different from a bzrdir with no branch at all.

As for the case of a bzrdir containing a repository and a working tree, one would be to try and duplicate a git style repository layout.  Something like this:

  ./repo -- a Bazaar repository
  ./repo/.branches/main -- a Bazaar branch without a working tree
  ./repo/.branches/otherbranch -- another Bazaar branch
  ./repo -- a lightweight checkout of .branches/main

At the moment it is not possible to get this setup with the command line client (it will refuse to make the lightweight checkout because the directory exists), but it is possible with some hacking.  Once it is set up, you can switch to other branches with "bzr switch".

I'm not sure how useful this is in practice, other than to show that a git style layout is possible.

Posted by David Allouche at Sun Dec 10 17:05:15 2006

Thanks to Wouter van Heyst (LarstiQ) for pointing out that the default behaviour of init-repo had not changed recently. And that, instead, it might change /after/ 0.13 to use --trees by default.