StupidBzrTricks

After working for Canonical for a year, I've collected a number of tricks that make Bzr easier/faster to use. I'm sharing them here in the hopes that they might be useful to other people, and that they might contribute their own.

Most of these are in the form of bash functions, so that I can just quickly type the function names rather than repeatedly typing tedious commands.

Here's my .bash_aliases file, for easier copy&pasting than the snippets below.

Make 'bzr diff' work like 'git diff'

   1 export LESS='XSERF'
   2 alias bzrdiff='bzr cdiff|less'

Easily back out of deep directories

   1 alias ..='cd ..'
   2 alias ...='cd ../..'
   3 alias ....='cd ../../..'

Create and enter directories in one step

   1 function mkcd {
   2     mkdir -pv -- "$1" && cd -- "$1"
   3 }

Easily manage tons of local branches

The following bits largely go together, and make the assumption that your local directory names match launchpad project/branch names, such as "~/src/launchpad-project-name/feature-branch-name".

Branch a project and enter it in one step

   1 function bzrbranch {
   2     [ $# -eq 0 ] && branch="trunk" || branch=$1
   3     bzr branch lp:$(basename $PWD) "$branch" && cd -- "$branch"
   4 }

Push a branch to Launchpad

   1 function bzrpush {
   2     bzr push lp:~/$(basename $(dirname $PWD))/$(basename $PWD) --remember
   3 }

Propose a merge on Launchpad

   1 function bzrpropose {
   2     if [ $# -eq 0 ]; then
   3         echo 'Please specify a commit message.'
   4     else
   5         default=$BZR_EDITOR
   6         export BZR_EDITOR=/bin/true
   7         yes|bzr lp-propose-merge -m "$@"
   8         export BZR_EDITOR=$default
   9     fi
  10 }

Commit & Propose in one step

Great if you're just making a small change.

   1 function bzrcompose {
   2     if [ $# -eq 0 ]; then
   3         echo 'Please specify a commit message.'
   4     else
   5         bzr commit -m "$@"
   6         bzrpush
   7         bzrpropose "$@"
   8     fi
   9 }

Example workflow

So, the above is a lot to take in, so here's an example of how I might use it day to day. I keep my local branches under ~/src/ but none of the above code enforces that specific directory.

   1 robru@rouge:~$ cd ~/src/
   2 
   3 robru@rouge:~/src$ mkcd unity
   4 mkdir: created directory ‘unity’
   5 
   6 robru@rouge:~/src/unity$ bzrbranch fix-some-bug
   7 Branched 3487 revisions.
   8 
   9 robru@rouge:~/src/unity/fix-some-bug$ $EDITOR some/file
  10 
  11 robru@rouge:~/src/unity/fix-some-bug$ bzrdiff
  12 
  13 robru@rouge:~/src/unity/fix-some-bug$ bzrcompose 'Fix that bug (LP: #nnnnn)'
  14 Committing to: /home/robru/src/unity/fix-some-bug/
  15 modified some/file
  16 Committed revision 233.
  17 Using default stacking branch /+branch-id/662123 at chroot-75432912:///~robru/unity/
  18 Created new stacked branch referring to /+branch-id/662123.
  19 lp:~robru/unity/fix-some-bug is already up-to-date.
  20 Commit message was not edited, use anyway? ([y]es, [n]o): yes
  21 Created new window in existing browser session.
  22 
  23 robru@rouge:~/src/unity/fix-some-bug$ ...
  24 
  25 robru@rouge:~/src$

And then you'll see the merge request pop open with your browser. The merge's commit message will match the commit message for the single commit being merged, and you'll be able to request reviews in the browser.

For a more in-depth edit that might require more than one commit, it's also easy:

   1 robru@rouge:~$ cd ~/src/
   2 
   3 robru@rouge:~/src$ mkcd unity
   4 mkdir: created directory ‘unity’
   5 
   6 robru@rouge:~/src/unity$ bzrbranch fix-some-bug
   7 Branched 3487 revisions.
   8 
   9 robru@rouge:~/src/unity/fix-some-bug$ $EDITOR some/file
  10 
  11 robru@rouge:~/src/unity/fix-some-bug$ bzrdiff
  12 
  13 robru@rouge:~/src/unity/fix-some-bug$ bzr commit -m 'Step 1 of fix.'
  14 Committing to: /home/robru/src/unity/fix-some-bug/
  15 modified some/file
  16 Committed revision 233.
  17 
  18 robru@rouge:~/src/unity/fix-some-bug$ $EDITOR some/other/file
  19 
  20 robru@rouge:~/src/unity/fix-some-bug$ bzrdiff
  21 
  22 robru@rouge:~/src/unity/fix-some-bug$ bzr commit -m 'Step 2 of fix.'
  23 Committing to: /home/robru/src/unity/fix-some-bug/
  24 modified some/other/file
  25 Committed revision 234.
  26 
  27 robru@rouge:~/src/unity/fix-some-bug$ bzrpush
  28 Using default stacking branch /+branch-id/662123 at chroot-75432912:///~robru/unity/
  29 Created new stacked branch referring to /+branch-id/662123.
  30 
  31 robru@rouge:~/src/unity/fix-some-bug$ bzrpropose 'Fix that bug (LP: #nnnnn)'
  32 lp:~robru/unity/fix-some-bug is already up-to-date.
  33 Commit message was not edited, use anyway? ([y]es, [n]o): yes
  34 Created new window in existing browser session.
  35 
  36 robru@rouge:~/src/unity/fix-some-bug$ ...
  37 
  38 robru@rouge:~/src$

Much less typing when you don't have to specify branch names more than once! The functions just use the directory names as implicit project/branch names.

StupidBzrTricks (last edited 2013-08-30 23:08:38 by robru)