Jeb Wilkins

Coding and climbing in Cumbria.

Branching in Bazaar (From Within TextMate)

I’ve spent a good chunk of time this weekend learning a little more about the internals of Bazaar. I decided to add branching support to the Bazaar bundle for TextMate. Initially this seemed simple, use cocoadialog to ask for a source branch, and a destination to branch into, then branch with a couple of lines to control bazaar, eg.

` from bzrlib import branch

b = branch.Branch.open(‘/tmp/mysrcbranch’) nb = b.bzrdir.sprout(‘/tmp/mydstbranch’).open_branch() `

The flaw in this plan became apparent when I tried to branch the Bazaar development repository, 60meg and lots of commits, and I got no feedback for the 10mins it spent branching. A helpful response from one of the guys on the Bazaar list told me I needed to create a UI Factory, since the code was by default using a silent one.

After a couple of hours picking through the code, I’d realised that this involved two classes, one which had various functions implement things like requesting a password from the user, or getting a progress bar object, and one implementing a progress bar. I decided to write one which backed onto cocoadialog, since I know nothing about writing UI’s for the mac. Initially i just copied and pasted existing classes and hacked up the functions to behave subtley differently so I knew the code was using my versions, eg. copied the dots progress bar and changed it to use pluses instead. This was actually the hard part, the progress bar was fiddly, in the end I just made every function ‘print’ when it was entered so I could see how bazaar was interacting with it.

Once I’d got that working, I just had to change the implementations to call CocoaDialog at the right points. The ProgressBar class opens a socket to CocoaDialog on first update, and then just writes() percentage updates when the class gets told to update the progress bar.

The only problem I’ve got at the minute is the cocoaui file is in a different (non sub) folder to the file with the Branch script. Currently this means setting the PYTHONPATH env var in TextMate to point at the folder with this file in, hopefully I can come up with a neater solution though. I’ve tried setting os.environ[‘PYTHONPATH’] but without much success.

[UPDATE: Fixed this by adding to sys.path instead, eg sys.path.append(os.environ[‘TM_BUNDLE_SUPPORT’]) ]

Hopefully the Cocoa UI Factory will mean adding push/pull support will be a lot simpler, since it can just reuse that factory. Likewise I’m hoping to use it in other places, like commit which can take a long time to run - at which point the user will get a nice progress dialog showing them that something is happening.

For anyone wanting to look at the source, download the TextMate bundle

http://www.jdwilkins.co.uk/wp-content/uploads/2007/09/bazaartmbundle.zip

Unzip it, its just a directory, in the Support subdirectory theres a single file cocoaui.py which has the python source showing how to write a custom UI Factory for Bazaar