convert a bazaar repository to a set of patches

A couple of weeks ago I was hacking on a GStreamer element from gst-plugins-bad and realized that I needed a way to record my changes in pieces, but not commit to the repository. GStreamer uses CVS, which does not support this workflow.

Bazaar to the rescue, then. I created a new local repository, in the plugin directory. It's as simple as typing bzr init, adding the files you want to track, and then committing as you make changes. I ended up committing a dozen patches or so.

Of course, when I was finished I wanted to push the changes upstream. Thus the point of this writing product, a script to turn a bzr repository into a series of patch files on disk:

set -e
patchbase=$(basename `pwd`)
if test -z "$outputdir"; then outputdir=.; fi

revno=`bzr version-info | grep revno | cut -d: -f2`
echo "exporting $(($revno)) patches..."
for ((i=0; $i<$revno; i=$i+1)); do
    echo "exporting $i..$(($i+1)) to $file"
    # dunno why bzr always returns $? != 0
    bzr log -r$(($i+1))..$(($i+1)) > $file || true
    bzr diff -r$i..$(($i+1)) >> $file || true

I then reverted my tree, applying and committing the patches one-by-one with e.g. patch -u -p0 < foo.diff.4. I'm sure there's some kind of more integrated plugin to do this, but a 10-minute shell script was easiest to hack out.

As an aside, bzr uncommit is quite useful for producing a readable history -- I often go back and modify the committed patches so that they are more understandable on their own.

Happy hacking!

6 responses

  1. Wouter Bolsterlee says:

    You might want to look into the "shelf" functionality offered by the (almost standard) bzrtools plugin set. It allows for stacked patches and seems to do the job you described perfectly well.

  2. Ali Sabil says:


    Maybe you definitely want to give the "record" plugin of bzr a try, it is exactly what you are looking for, and on top of that it records the patches in a patches/ subfolder manageable by quilt.


  3. wingo says:

    Ali: The link on to the record plugin seems to be in the "out of date" section.

  4. James Henstridge says:

    Perhaps Tailor can do what you want. I've never used it to convert from Bazaar to CVS before though, so it is the kind of thing you'd want to try on a copy of the repository first.

  5. Steven says:

    Git can definitely be used to import a CVS repository, but I'm not sure if it can directly convert git commits back into CVS commits. In either event, its as easy as:

    git format-patch HEAD~N

    to convert the last N commits into patches. For subversion its even easier, as git-svn allows a bidirectional workflow. You fetch the subversion repo with git, make you changes in as many chunks as you like with git, and then you can have git-svn send each of your local changes back to svn as a commit.

  6. wingo says:

    Steven: Neat trick!

Comments are closed.