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 provided as source. On unix, to install it as a plugin, run:
$ bzr branch lp:bzr-pipeline ~/.bazaar/plugins/pipeline
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 $ bzr diff === modified file '.bzrignore' --- .bzrignore 2009-06-23 20:20:39 +0000 +++ .bzrignore 2009-07-14 01:55:45 +0000 @@ -62,3 +62,4 @@ ./doc/en/user-guide/latex_prepared ./doc/en/user-guide/*.pdf ./.ccache +./pipes
As you can see, reconfigure-pipe added an entry to .bzrignore, to ignore a directory named 'pipes'. When you reconfigure, Pipelines moves your branch into this directory, and other branches will be added there as you command. It's a good idea to commit this addition to .bzrignore, but Pipelines leaves the choice to you.
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 correctly set.
$ 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:
$ 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 bar --before foo -r submit:
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 added .bzrignore ...
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
