Bazaar

Bazaar

 




Wiki Tools

  • Find Page
  • Recent Changes
  • Page History
  • Attachments

Bazaar Pipeline

The pipeline plugin helps you organize your changes into sections called "pipes"

Pipelines can help you:

  • focus on each set of changes as a coherent piece, without being distracted by other sets of changes.
  • respect diff size limits when submitting changes
  • avoid reviewer fatigue when submitting changes for code review
  • maintain a set of patches against an upstream branch

Bugs tracking and code management is at Launchpad.

Installation

Pipeline is packaged in Ubuntu universe since Maverick and Debian since Squeeze.

You can also run it from source. On Unix, to install it as a plugin, run:

$ bzr branch lp:bzr-pipeline ~/.bazaar/plugins/pipeline

You may first need to create the ~/.bazaar/plugins directory.

On Windows, replace ~/.bazaar/plugins with your actual plugins directory.

Getting Started

If your source code is not in a lightweight checkout, you'll need to convert it into one, first. To do this, enter your source code tree and run "reconfigure-pipeline":

$ cd bzr.dev
$ bzr reconfigure-pipeline

When you reconfigure, Pipelines moves your branch into the .bzr/branches directory, and other branches will be added there as you command. This is compatible with the bzr-colo plugin.

A pipeline is a series of one or more pipes, and a pipe is a branch, so every branch is already a pipeline with a single pipe. For a chuckle, try this:

$ bzr init foo
Created a repository tree (format: pack-0.92)
Using shared repository: /home/abentley/foo/
$ bzr show-pipeline foo
*  foo

So if your code was already in a lightweight checkout, you don't have to do anything to use it with Pipeline. It already is a pipeline.

To add a pipe, use the add-pipe command:

$ bzr add-pipe fix-NEWS
Tree is up to date at revision 4531.
Created and switched to pipe "fix-NEWS"

add-pipe adds a pipe with the name you specify to the pipeline. By default it's added after the pipe you were on, and your checkout switches to that pipe.

$ bzr show-pipeline
   bzr.dev
*  fix-NEWS

Now show-pipeline indicates that there are two pipes, and uses * to mark the current pipe. Pipelines flow from the top to the bottom. So changes in bzr.dev will flow into fix-NEWS.

Developing a series of changes with Pipeline

Let's say you're working on a fairly major change that you'll break up into three parts, called part-1, part-2, and Morpheus. Okay, we'll call them part-1, part-2 and part-3, just to be consistent.

You'll start off by creating a new pipeline to hack in:

$ bzr branch project big-change
Branched 718 revision(s).
$ cd big-change
# when we move the pipe into ./pipes, we'll use its nickname, so let's set it here.
$ bzr nick part-1
$ bzr reconfigure-pipeline

Now, you can hack away at part-1. Eventually, you'll think you're done, and move on to part-2:

$ bzr add-pipe part-2
Tree is up to date at revision 718.
Created and switched to pipe "part-2".

Now you can start working on part-2. Sooner or later, you'll run into something you should have done as part of part-1. Maybe you forgot some documentation, maybe there's a bug, maybe you introduced an API but forgot to include a vital parameter. At that point, you can switch back to part-1. You don't need to worry about your uncommitted changes. They will be stored in part-2's branch when you switch, so long as you use switch-pipe (not switch).

$ bzr switch-pipe part-1
Uncommitted changes stored in pipe "part-2".

When all your changes to part-1 have been committed, you can apply them to the pipes further down the pipeline with the pump command:

$ bzr pump

If the changes cannot be applied without conflicts, Pipeline will switch to the pipe where conflicts occur, so that you can solve them manually.

Now you can switch back to what you were working on.

$ bzr switch-pipe :next

Now, you'll find that all the changes you made in part-1 are already present, and your uncommitted changes are back. You can now finish up part-2 and continue on to part-3.

But while you've been working, other people have made changes to the project. It's best to merge often to reduce the risk of conflicts. The pump command also makes this easy, assuming your submit_branch is set correctly.

$ bzr pump --from :submit

Unlike a normal pump, this will merge changes into your first branch from its submit branch and commit. Then it will apply all the changes from your first pipe to your second pipe and commit. The process will continue until all your pipes have the changes from the submit branch, or conflicts are encountered.

At some point, you may wish to push your pipeline to a public location. Pipeline supports this via the "sync-pipeline" command:

$ bzr sync-pipeline bzr+ssh://example.org/part3

Finally, when you're ready to submit your code, you can do it in pieces.

If you're using lp-propose to submit your code, it will automatically detect the previous pipe and use it as the prerequisite branch:

$ bzr switch-pipe :first
$ bzr lp-propose -m "First section"
$ bzr switch-pipe :next
$ bzr lp-propose -m "Second section"
$ bzr switch-pipe :last
$ bzr lp-propose -m "Final section"

You can also submit your code using send:

$ bzr switch-pipe :first
# The first pipe is special, because it doesn't contain any changes from earlier pipes.
$ bzr send
$ bzr switch-pipe :next
# This is a request to merge all the changes in part-2 that aren't in part-1
$ bzr send -r ancestor::prev..
$ bzr switch-pipe :last
# This is a request to merge all the changes in part-3 that aren't in part-2
$ bzr send -r ancestor::prev..

Splitting a change into two pieces

First, you need to create a new pipe with none of your changes:

$ cd foo
$ bzr add-pipe --before -r submit: bar

Now, merge some of the changes from your original branch into the new one:

$ bzr merge -i :next
$ bzr commit -m "made changes"

(Note: bzr 1.17 and earlier does not support merge -i. If your bzr doesn't support merge -i, you can use bzr shelve --destroy -r branch::next instead, but the prompts will be confusing.)

Finally, pump your changes into the original branch:

$ bzr pump

That's it!

Maintaining a series of patches against software from tarballs

First, you'll need to import your initial tarball to bzr. The "import" command from bzrtools does this:

$ bzr import bzrtools-release/bzrtools-0.8.tar.gz bzrtools-import
$ cd bzrtools-import/
$ bzr reconfigure-pipeline
$ bzr commit -m "Import bzrtools 0.8"
Committing to: /home/abentley/bzrtools-import/pipes/bzrtools-import/
added .be
...

Now, let's add a patch. (The "patch" command also comes from bzrtools.):

$ bzr add-pipe bt-patch
Tree is up to date at revision 1.
Created and switched to pipe "bt-patch".
$ bzr patch ../bt-patch
$ bzr commit -m "Added the patch"
Committing to: /home/abentley/bzrtools-import/pipes/bt-patch/
modified setup.py

Next, let's apply the next tarball:

$ bzr switch-pipe bzrtools-import
$ bzr import ../bzrtools-release/bzrtools-0.9.0.tar.gz
$ bzr mv --auto
$ bzr add
$ bzr commit -m "Imported 0.9" --no-strict
Committing to: /home/abentley/bzrtools-import/pipes/bzrtools-import/
deleted .bzrignore
modified NEWS
...
$ bzr pump

The pump command will apply the changes in this new release to the bt-patch pipe. You can re-generate the patch at any time:

$ bzr switch-pipe bt-patch
$ bzr diff -r ancestor::prev

Manually manipulating the pipeline

In rare circumstances, you may need to fix a broken pipeline by disconnecting/reconnecting a pipe to the pipes that refer to it. To clear the pipe's previous pipe:

$ bzr config --scope=branch prev_pipe=""

To clear the pipe's next pipe:

$ bzr config --scope_branch next_pipe=""