• Resources
Ubuntu DC LoCo Team

User login

  • Request new password

Navigation

  • Events Calendar
  • Join Us!
  • Resources
  • Running Events

Washington, DC flag

A quick introduction to bzr

Submitted by kjcole on Sun, 2009-07-12 08:10

Kevin Cole
Copyleft 2006.06.02

The author wishes to express much thanks to James Blackwell, the Ambassador of bazaar, for both his documentation and his patience in IRC. Also, Martin Pool's documentation was rather helpful in getting me started. For some of their work, see the Resources section at the end of this document.

  • Introduction
  • Assumptions
  • Configuration
  • Initializing
  • Committing
  • Pulling
  • Resolving
  • Resources

Brief introduction

A Revision Control System (RCS) is a suite of programs that allows developers to coordinate and chronicle their work. Each change or revision to any of the files being controlled by such a system can be tracked by date, developer or comment. The set of files being controlled can also be "rewound" or rolled back to a previous state. In addition, RCS's have mechanisms to prevent collisions and conflicts — either by preventing more than one user from editing any file at any given time, or by indicating differences between two conflicting versions of the same file, and offering methods to merge files and resolve conflicts.

A distributed RCS allows each developer to make their own independent copy of a set of files comprising a project. They can then edit the individual files and record their changes in a local "catalog". (Traditionally, the record of changes has been kept in a central location.) A project coordinator can then merge the various branches together into a master branch.

bzr (sometimes known as bazaar-NG) is one such distributed revision control system.

Assumptions

In an ideal world, each of the developers will have access to a system with both bzr and a web server installed, as well as a public HTML directory to which they can write. Having bzr branches live in web-browsable directories makes it easier for the lead developer to merge branches together periodically.

Preparation/Configuration

  1. In your home directory, create a directory named .bazaar
    cd ~
    mkdir .bazaar

  2. Using the editor of your choice, create a file named bazaar.conf in the .bazaar directory with the following contents (replacing the red text with your own information):
    cd ~/.bazaar
    nano bazaar.conf
    # bzr configuration file
    # Last modified by Kevin Cole <me@some.domain.tld> 2006.02.08
    #
    # Built following the directions found in the bzr tutorial
    # at http://bazaar.canonical.com/IntroductionToBzr
    #

    [DEFAULT]
    email=Kevin Cole <me@some.domain.tld>
    Actually, these days you can get the important line inserted even easier with the command:
    bzr whoami "Kevin Cole <me@some.domain.tld>"

  3. Create a public_html directory if it does not already exist, and just to be nice to the community you work with, make a bazaar directory within it.
    cd ~/
    mkdir -p public_html/bazaar

  4. (Optional) Those of you who are not heathens doing penance with vi will want to make your lives easier by encouraging bzr to use the one true editor . Adding a few lines to the end of your ~/.bash_profile will take care of that.
    cd ~/
    nano .bash_profile
    CSHEDIT=/usr/bin/emacs
    EDITOR=/usr/bin/emacs
    VISUAL=/usr/bin/emacs
     
    export CSHEDIT EDITOR VISUAL

The steps above set the stage for all of your future interactions with bzr.

Starting or joining a project

Each bzr repository consists of the files in the project you're working on, and a hidden directory named .bzr. This directory is used to keep a history of all the differences between various revisions, and other info that bzr needs to keep track of your universe.

Therefore, separate projects need separate directories in which they can each keep their very own .bzr directory

If you're beginning your own project, you initialize the .bzr directory with the command:

mkdir ~/public_html/bazaar/project
cd ~/public_html/bazaar/project
bzr init

On the other hand, if you're not starting from scratch, you'll create a branch, of someone else's repository which creates the directory you need. You will need the URL of the repository you want to branch from.

cd ~/public_html/bazaar/
bzr branch http://dc.ubuntu-us.org/~kjcole/bazaar/gin
ls
cd gin

At this point you should be able to begin work on the actual code.

Recording your changes

Periodically (frequently), you should let bzr know what you've been up to, before you forget what you've added, changed or deleted. Typically, you'll be executing the some of the following commands in the following order.

bzr status     # lists which files have been changed or added since the last time you committed your changes
bzr ignore filename     # logically enough, this tells bzr to ignore that file. NOTE: This creates a file in the current directory named .bzrignore, which has one regular expression per line for what to ignore.
bzr add     # Adds any files of status "unknown".
bzr mv oldfilename newfilename     # IMPORTANT: Use this in place of a simple mv command, so that bzr knows a file has been renamed. Otherwise, bzr thinks an old file has been removed and a new one added.
bzr commit -m "comment"     # Commits your changes and adds a comment. Leaving off the -m "comment" will crank up your favorite editor and allow you to leave a more detailed comment.
bzr sign-my-commits     # (OPTIONAL) If you have your GPG keys on the system where you're commiting your work, you can sign the commits.

NOTE: If you chose a default editor other than vi, bzr leaves droppings after a commit (without the -m) in the form of a temporary file named bzr_log.pseudo-random-string~ which you should remember to get rid of manually ASAP.

Also, with regard to signing commits... If you wait until you've made several commits, and then sign, you will need to type in your passphrase a gazillion times — once for each commit you've made.

Playing well with others

Ok, so now you've been existing in this vacuum where you've been happily modifying, adding and religiously committing your changes without a care as to what others are doing. Now, the package god wishes to see what you've been up to. He or she "pulls" your changes (as well as the changes of others editing in their own private universes), twiddles bits, sanctions everyone's work and commits what becomes the latest and greatest version... Now it's time for you to pull from that central, master version, which will incorporate any approved changes made by others into your version. In effect, both the lead developer and you are regularly downloading updates from each other.

bzr pull http://dc.ubuntu-us.org/~kjcole/bazaar/gin
bzr log | most
bzr vis

If you merely type bzr pull, bzr will assume you want to pull from the URL you branched from. So, generally you can get away with the simpler form, unless you're the lead developer and need to pull from several different locations.

The bzr log command provides a log of the commits made by all, including the author, time and comment associated with each commit. Since the log can get rather long, I like to pipe it through my favorite pager, most. But if you don't have most installed you can use less in its place. (Frighten your English teachers: less is better than more, and most is better than less. ) The most package is available in the Ubuntu universe apt repository.

bzr vis is "really cool" if it's available. It will pop open a visualization window that shows the log in a considerably more interesting format. It also gives you a nice way to see diffs between versions. (The visualization add-on isn't bundled with bzr, and has to be fetched as a separate package named bzrk. In addition, if X-windows is not forwarding, or other weirdness, bzr vis may be unable to open a window on your screen.)

If you're the lead developer/master of all you survey, you can opt to use bzr push, rather than waiting for your lord and master to pull from you.

bzr push sftp://kjcole@dc.ubuntu-us.org/home/kjcole/bazaar/gin/

NOTE: In my experiments, the sftp protocol didn't appear to understand /~kjcole/. It required /home/kjcole/.

The push sends only the changed(?) meta information from the local .bzr directory to the remote .bzr directory. It does NOT actually change the remote target files. (This is because sending large changes across the wire is expensive in terms of bandwidth usage.) So, once out on the remote system, one needs to do the update.

ssh dc.ubuntu-us.org
cd ~/bazaar/gin
bzr log | most
bzr update

Although the log will show the changes as having happened, a check of a supposedly changed file will show that changes, in fact, have not been applied. The update command should read the info recently pushed into the .bzr directory and apply the changes to the actual source files.

Conflict resolution: Here be dragons

DISCLAIMER: I haven't worked with any other RCS and am also relatively new to bzr. So far, I haven't really done anything collaboratively with it.

Most of the burden for resolving conflicts, I hope, will fall to the lead developer. That person will be deciding which changes from multiple developers on a project to keep or reject. Drones, slaves and peons should refrain from making new commits while the project god is ruminating over all the branches. That said, it's a nice theory, but may not work in practice.

Should the unthinkable happen, and you end up pulling changes from somewhere that conflict with your own, bzr will offer some suggestions on what to do.

ls
TODO ...

bzr pull
Inventory ok.
bzr: ERROR: These branches have diverged. Try merge.

bzr merge
bzr: WARNING: Text conflict in TODO
1 conflicts encountered.

ls
TODO TODO.BASE TODO.OTHER TODO.THIS ...

At the beginning of the session, there was a file named TODO. bzr could not successfully pull the changes from elsewhere, because it would conflict with changes in the current branch you're working on, and it suggested you try a merge. The bzr merge also had problems. It altered the contents of TODO and produced three spin-off files. The results are the following four files:

  • TODO is an attempt at a merged version of the file, with added text showing which parts came from which source.
  • TODO.BASE is the original file from which the two conflicting versions came.
  • TODO.THIS is the file with YOUR changes.
  • TODO.OTHER is the file with the other person's changes.

At this point, what I do is examine all the conflicting files, edit whichever one involves making the fewest changes, and change the name of that file to whatever the merged file should have been named. When that's done, issue:

bzr resolve TODO
bzr commit

I'm not certain that the above is the proper way to do it, but it appears to work. The bzr resolve command gets rid of the .BASE, .THIS and .OTHER files for you.

Resources

There's a lot more that bzr can do, and many of the commands have optional arguments. The curious should look at the man pages as well as the documents referred to at:

  • Bazaar Tutorial
  • Bazaar User Guide
  • The Independant: A short story by James Blackwell
  • Miscellaneous notes at Docbox

In particular, the two documents from Canonical listed there are quite useful. My log and IRC conversation are considerably less so.

For help with GPG and digital signatures, see:

  • http://dc.ubuntu-us.org/resources/tutorials/gpg.html
  • https://wiki.ubuntu.com/GnuPrivacyGuardHowto
  • http://www.hlug.org/presentations/gpg/gpg.html
  • http://www.youdzone.com/signature.html

—
http://dc.ubuntu-us.org//resources/tutorials/bzr-intro.html

  • Sermon on the Umount
‹ Tutorials and Other Resources up Sermon on the Umount ›
  • Login to post comments
Ubuntu — "Linux for Human Beings"