Using Bazaar Like Git + ‘repoalias’ Plugin

Continuing my exploration of distributed version control systems, I decided to take a quick look at the Git:

Managing Branches

A single git repository can maintain multiple branches of development. To create a new branch named “experimental”, use:

$ git branch experimental

If you now run

$ git branch

you’ll get a list of all existing branches:

  experimental
* master

That’s strange, I thought. Bazaar does it a bit differently. In Bazaar, the branches are often stored in a shared repository, which is just a special folder that contains the branches in it as subdirectories, but unlike Git, the repository is typically a “normal” folder that contains branches which are stored as subdirectories in plain sight to the developer.

Here’s an example from the Bazaar User Guide:

repository/       # Overall repository
 +- trunk/        # The mainline of development
 +- branches/     # A container directory
 |   +- foo/      # Branch for developing feature foo
 |     ...
 +- tags/         # Container directory
     +- release-X # A branch specific to mark a given release version
        ...

Hmm… I actually like how Git does it. Git “already works” with the way I have my existing projects setup. I don’t want to move my projects to match the directory structure shown above. Is there any way to use Bazaar in a Git-like manner? Well, I suppose you already know the answer to that, as I wouldn’t have much of a blog post to write if there wasn’t! 🙂

Setting up a Git-like workflow with Bazaar

Being completely new to Bazaar, and to DVCS’ in general, I decided to ask the folks over at #bzr. They were very helpful, and fairly quickly ‘mzz’ had an answer:

First, we cd into our project, which is already setup as a bazaar branch:

cd path/to/myproject

Next, we run the following command:

bzr init-repo --no-trees .bzr-repo

That creates a hidden shared repository inside the project folder called .bzr-repo. We add the --no-trees option to tell Bazaar not to create unnecessary copies of the working tree.

Note that this is quite different from how repositories in Bazaar are normally used, usually they’re the parent directory.

bzr ignore .bzr-repo

We add the repository itself to the ignore list so that it’s not tracked.

Next, we commit the changes and create the main branch, called “trunk”:

bzr commit -m "added .bzr-repo to ignore list"
bzr branch . .bzr-repo/trunk

At this point we have two branches, the one in .bzr-repo/trunk and the branch we started with. This is no good, we want to be deal with only one branch at a time—the one we’re currently working with, and we want that branch to be one of the ones in .bzr-repo.

Thus enters the concept of a lightweight checkout. A checkout is very similar in concept to its SVN counterpart, you have a folder were you can make changes to files, and when you commit them they are sent off to some central location. One of the main differences between checkouts in Bazaar and checkouts in SVN is that in Bazaar the revision history is stored locally within the checkout itself. But in our setup, we don’t want that since each branch is stored locally anyway. Having two copies of it wouldn’t offer any advantage and would just take up space. A lightweight checkout lets us have a checkout without a revision history.

We can tell Bazaar to change the current branch into a checkout that points to .bzr-repo/trunk by using the reconfigure command:

bzr reconfigure --lightweight-checkout --bind-to .bzr-repo/trunk .

That’s it! 🙂

Now we can continue our work as usual. Let’s test this out by adding a new file to the project:

$ echo "Version 1.0" > CHANGES
$ bzr add CHANGES
adding CHANGES $ bzr commit -m "added CHANGES" Committing to: /Users/gslepak/myproject/.bzr-repo/trunk/ added CHANGES Committed revision 2.

Everything seems in order. We can now use Bazaar like Git:

$ bzr branch . .bzr-repo/experimental
Branched 2 revision(s).
$ bzr switch .bzr-repo/experimental
Tree is up to date at revision 2.
Switched to branch: /Users/gslepak/myproject/.bzr-repo/experimental/

Since Bazaar doesn’t have an equivalent to the args-less git branch to list the available branches, we just use plain-old ‘ls’:

$ ls .bzr-repo/
experimental/ trunk/

At this point you might be wondering if there’s a way to get around having to type out the path to the repository each time you use bzr branch and bzr switch

Introducing the ‘repoalias’ Plugin

I asked that question on #bzr and mzz snapped into action, within a few minutes he had a working plugin ready that did just that. Needless to say my head was reeling from his Python kung-fu. 🙂

Repoalias allows you to reference the branch’s repository like so:

bzr branch . repo:experimental
bzr switch repo:experimental
... do work ...
bzr switch repo:trunk
bzr merge repo:experimental
... etc ...

Getting the plugin is simple:

mkdir -p ~/.bazaar/plugins    # create the plugins folder if it doesn't exist
cd ~/.bazaar/plugins
bzr branch lp:~marienz/+junk/repoalias

That’s it! Many thanks to mzz and the folks at #bzr for helping me understand this stuff!

Installing Bazaar 1.16 on OS X [Updated]

Recently I decided to bite the bullet and move away from Xcode’s Snapshots to using a DVCS. After checking out Git, Mercurial, and Bazaar I finally settled on the latter, for now at least.

Bazaar is a great, it has excellent documentation on a very well designed website, it’s incredibly easy to use (one of its design goals) so you can focus on what’s important (coding), it has support for both distributed and centralized workflows, it supports pushing and pulling from SFTP servers that do not have bazaar installations, and it uses revision numbers (instead of hashes), and it does so in a very intelligent way.

Unfortunately the latest version doesn’t seem to come in a tidy OS X Installer package, nor is it available via MacPorts (yet), so here are some tips to install it from source.

If you’ve previously installed Bazaar using the package installer you’ll probably want to clear out some of the files it installed prior to installing the new version:

cd /Library/Python/2.5/site-packages
sudo rm -rf bzr*
sudo rm -rf Loom-1.4.0dev0-py2.5.egg-info
sudo rm -rf subvertpy*
sudo rm -rf Extmerge-r10-py2.5.egg-info
sudo rm -rf qbzr-0.9.9-py2.5.egg-info
# we'll install the latest versions of these in a bit
sudo rm -rf BzrTools-1.14.0-py2.5.egg-info
sudo rm -rf pycrypto-2.0.1-py2.5.egg-info
sudo rm -rf paramiko*

We do that to avoid conflicts and because we want to install these plugins ourselves, so that we can use the latest versions.

Installing Dependencies

As mentioned in the note above, and on the InstallationFaq, there are 3 things that come with the package installer that you should install: Paramiko and pyCrypto (for SFTP support), and BzrTools.

Because of the way we’re installing Bazaar, you should install BzrTools *after* installing Bazaar 1.16 (detailed below). Installing Paramiko and pyCrypto is simple though, as you only need to download Paramiko (its installer will grab pyCrypto for you):

  1. Grab the latest version of Paramiko, as of this writing it’s 1.7.2:
  2. Extract the contents of the archive and ‘cd’ into the directory
  3. To build and install run these commands:
    python setup.py build
    sudo python setup.py install

Optionally, the InstallationFaq suggests installing Pyrex to speed things up.

Installing Bazaar 1.16

Download the source for 1.16 (direct link). After you’ve extracted it run these commands from the source dir:

python setup.py build
sudo python setup.py install --home /usr/local
sudo mv /usr/local/lib/python/bzr* /Library/Python/2.5/site-packages/

Note: On Snow Leopard the default Python install is 2.6, not 2.5.

Installing Bazaar Plugins on OS X

This too isn’t very clear from the Bazaar Plugins page. To install a plugin follow these steps:

  1. Pick a plugin from the plugins page and grab its branch URL, for example the URL for Rebase is:
  2. In some directory run:
    bzr branch [branch-URL]
  3. That will download the plugin source. ‘cd’ into the directory, in the above example it’s “trunk”.
  4. Build and install the plugin using the same commands as you used to install the dependencies.

That should do it. One note is that a lot of the plugins are hosted on launchpad, in which case grabbing them is simple (using ‘bzr-search’ as an example):

bzr branch lp:bzr-search

Now you can enjoy the benefits of running the latest version. 🙂

Cloak 1.1! + Artists: Win an Espionage license!

Cloak has been updated to 1.1 (download) and this brings two much needed improvements: Mac OS X 10.4 support, and an icon!

Yes, the new icon looks like it’s out of a video game.. I swear I’m a much better coder than I am an artist! Unfortunately John has too much on his plate right now and therefore cannot give Cloak a proper icon, which is why I’m holding a contest:

Win an Espionage license! (Or $24.95)

Cloak needs a nice 512×512 icon of a cloaked figure with glowing eyes. If you think you can do a better job we welcome you to try, just post a link to your icon in the comments below.

The winner will get to choose his or her prize: a free license to Espionage or $24.95 via PayPal. Additionally, your name will be placed in Cloak’s about box with an optional link to your site.

Please remember to enter a real email address when posting a comment so that we know where to reach you.

The winner (if there is one), will be announced at the end of the month, June 30th, 2009.

Enjoy! 🙂

ebswitch: EventBox Profile Switcher

My favorite Twitter client is EventBox by The Cosmic Machine. And while it has a million great features like support for Instapaper and a great interface, it’s missing one critical piece of functionality and that is support for multiple profiles. However, it’s still possible to use EventBox with multiple profiles, but perhaps not at the same time.

One solution is a great little program called rooSwitch. It can be used with EventBox to give you the ability to switch between different isolated profiles, each with its own settings. You could configure rooSwitch with multiple EventBox profiles, say for example one for each Twitter account that you use:

rooSwitch with two twitter profiles

While rooSwitch is great, I don’t have much use for it besides switching EventBox profiles, and I’m a terminal fiend anyway, so I wrote a simple newLISP script called ebswitch that does this for me. Here’s an example session:

$ ebswitch
ebswitch version 0.2
Usage: /usr/local/bin/ebswitch twitter_profile_name
$ ebswitch espionageapp
taoeffect => espionageapp
Creating fresh account for: espionageapp
Successfully switched to profile: espionageapp
    ... EventBox opens, enter 'espionageapp' login information ...
$ ebswitch taoeffect
Quit EventBox? [y|n]: y
espionageapp => taoeffect
Successfully switched to profile: taoeffect

Installing ebswitch

ebswitch is a newLISP script, so to use it you’ll need to make sure that newLISP is installed (Intel/PPC), and don’t worry, one of the great things about newLISP is how small it is. Then, after downloading ebswitch to your Desktop, install it into your /usr/local/bin (or /usr/bin) like so:

$ cd ~/Desktop
$ sudo install ebswitch.lsp /usr/local/bin/ebswitch
Password: enter admin password

Enjoy! 🙂

Update: ebswitch 0.2 adds more intelligence and can now quit EventBox for you.

eb_switch.lsp

Espionage 2.0.8 Released!

Espionage 2.0.8 is primarily a bugfix update to 2.0.7:

  • FIXED: Issue relating to ACLs and “fixing folders” introduced in 2.0.7
  • FIXED: Issue where help for application associations would require an internet connection
  • IMPROVED: Address Book template sets AddressBook folder to autounlock by default
  • IMPROVED: Changed Adium template to encrypt entire app support folder (fixes issue w/its auto-update)

One note worth mentioning is that if you’ve encrypted Adium with Espionage, you may want to re-encrypt it using the new version, as the new version now encrypts the entire Adium 2.0 folder as opposed to just the Users folder, and this may fix an issue that could arise with Adium’s auto-update.

Since they were released so close to one another, you may wish to read what’s new in 2.0.7 if you haven’t yet.

Cloak: Manage Your Invisible Files

Update: Cloak 1.1! + Artists: Win an Espionage license!

The other day we received a nice email from Nenette asking us whether Espionage could hide its encrypted folders. While Espionage does not have this capability, the desired effect is achievable by placing the Espionage’d folder inside of a hidden folder.

There are two main methods of making a file or folder invisible in Mac OS X:

  1. Prefix the file/folder name with a dot. (Example: .Hidden)
  2. Set a special “invisible” attribute on the file.

I began a search to find a program that I could recommend to accomplish this task, but wasn’t able to find one to my liking. Racing against our self-imposed 24-hour support-response time limit, I managed to whip out Cloak1:

The application itself should hopefully be intuitive enough as to be self-explanatory, although one tip is that you can open a file or folder by double-clicking on it.

With regards to Espionage, it should be noted that hiding an encrypted folder is not necessary, as without the password to the folder (or the master password) its contents are not visible, nor can they be accessed. Still, maybe someone will find this application useful.

Enjoy! 🙂

1Originally it was called “Invisinator”, but my good friend Lizzy suggested Cloak, a far less stupid sounding name.

Espionage 2.0.7 Released!

Espionage 2.0.7 is finally here, and for a “minor” update, it packs decent punch. If you’ve been waiting to update, you should do so now as 2.0.7 adds many improvements and important fixes:

  • NEW: Added app templates for The Hit List, OmniFocus, and Bento
  • NEW: You can lock a folder simply by ejecting it (convenient for Path Finder users)
  • NEW: Templates have preliminary support for dependencies (ex: Address Book data -> Mail)
  • NEW: Templates now automatically disable Spotlight for folders that don’t need it
  • NEW: Initial appearance of status menu item. Currently only “Backup Now” available, more to come
  • FIXED: Possibly fixed a situation where helper could hang if there were too many items to autounlock
  • FIXED: Situation on some machines preventing the encryption of folders in Home folder like Documents (thanks Pol!)
  • FIXED: Added Mail Downloads folder to Mail association template (thanks Pol!)
  • FIXED: Removed logging of unnecessary error message related to custom icons
  • FIXED: Bug preventing custom icon from showing while folder is locked
  • FIXED: Situation that could prevent external disks from unmounting
  • FIXED: Situation in which settings for the wrong folder are shown after a folder is removed from Espionage
  • FIXED: Table view not being key after an operation completed
  • FIXED: Situation that could prevent proper uninstall on expired trial using separate keychain
  • FIXED: Issue relating to helper stop/start preference not being set correctly
  • FIXED: Issue relating to start/stopping helper where folders would be incorrectly displayed as being unlocked
  • FIXED: Issue related to opening an association during the opening of another one
  • IMPROVED: Added built-in check for Logitech Control Center
  • IMPROVED: Improved aesthetics of some alerts
  • IMPROVED: Modified File menu for clarity
  • IMPROVED: Removed auto-backup on mount, use status menu “Backup Now” instead
  • IMPROVED: Added ACLs to protect folders while they’re disabled (hopefully preventing some “Saved Folder” situations)
  • IMPROVED: Added extra warning to prevent users from removing suggested associations from new folder sheet
  • IMPROVED: Behavior when logging out
  • IMPROVED: Compatibility with MobileMe sync (though syncing manually and maintaining backups are strongly recommend)
  • IMPROVED: Compatibility with ExpanDrive

Overview of Significant Changes

Removed auto-backup on mount

Perhaps a great example of how taking a step backward can be a step forward, we’ve removed the ‘auto-backup on mount’ feature that was introduced in 2.0.4. While convenient, it wasn’t a very good idea, as it could potentially lead to a good backup being inadvertently overwritten with a bad one.

Instead, Espionage now has a status menu item for this purpose:

Status Menu Item

Note: “Backup Now” will be disabled if the backup destination isn’t available, and as hinted by the menu itself, we plan on adding much more to it in a future update.

Eject to lock

Espionage will now also detect if a folder is ejected (as opposed to locked via the “Lock” contextual menu). This can be useful for Path Finder users who can choose to view Espionage’s unlocked folders in the sidebar:

Eject-to-unmount

MobileMe compatibility

Previous versions of Espionage could run into problems with MobileMe sync, this update should hopefully address those issues. If you use MobileMe Sync, we still strongly recommend that you make sure that you use Espionage’s backups to backup your data. If you still experience issues with MobileMe Sync and Espionage, then switch to manual sync and only sync when Espionage isn’t locking or unlocking data.

Template support for dependencies

Some application data is used by programs other than the application itself. A great example of this is Address Book, whose data is accessed by applications such as Mail, iCal, iChat, and others. We’ve therefore added these dependencies to the Address Book template as application associations to ensure that Address Book’s data is unlocked before any of these applications try to use it.

This means that if you encrypt Address Book using the template, Espionage will prompt you for the password when launching Mail, iCal, or iChat if the Address Book data is locked. You may therefore wish to set it to auto-unlock at login.

Spotlight disabled for folders that don’t need it

Some applications store their data in many folders, and not all of these folders need to have a Spotlight index. Therefore the templates now disable Spotlight for folders that don’t need it, improving performance when opening Espionage’d applications that store their data in many folders.

We will add a checkbox to toggle Spotlight support on a per-folder basis soon, but for now you can easily disable Spotlight for any Espionage’d folder by following these steps.

Enjoy! 🙂

P.S. Espionage is on twitter now, follow for Espionage related news.

Refills: A Sustainable Solution

What if you could get refills for all of the products that you buy that come in containers?

We’ve become accustomed to the notion that every product must come in its own packaging, that this is “obvious” and that it’s the only way things can be done.

Every day I use a variety of container-based products (CBPs for short): shampoo, face-wash, toothpaste, liquid soap, orange juice, etc. etc. The list of CBPs goes on. This causes a huge strain on the environment. Companies use giant factories across the world to manufacture hundreds of thousands, and in some cases millions of CBPs. For each CBP resources and energy are used to create the container, then all of these little containers are shipped all over the world in an inefficient manner.

Wouldn’t it be great if we could get rid of most of them? I think such a world is possible.

This brings up several questions: Could this cause difficulties for brands to compete? After all, you recognize that this particular brand of sugar-water belongs to Pepsi because it comes in a CBP that has the Pepsi logo on it. And how are you to know what’s in your shampoo if it doesn’t have a container to list the ingredients?

Imagine the following:

A Different World

A consumer walks into a local grocery store in search of body wash. He grabs a sleek bottle of Product 5eX promising to make him more attractive to the opposite sex. Except, this isn’t a CBP, in fact, while the store’s isles are packed with various bottled products much as they are today, there’s not a single CBP to be found, what our gullible protagonist holds in his hands is actually an RBP—a refill-based-product.

After weeks of usage and several unsuccessful attempts at attracting a mate, our friend runs out of Product 5eX and decides that perhaps he hasn’t used it long enough and so drives back to the grocery store in search of more. However, instead of going back to the isle where he originally found it, he places the empty container, along with empty containers of toothpaste, face-wash, and 9-liter bottle of cola on a conveyor belt at the front of the store while swiping his credit card. After shopping around for various food products inside he’s ready to checkout, and so are his RBPs.

In such a world there are many possibilities. Perhaps you could use a generic container and simply use the product’s unique ID number to refill it. There could be a huge online database that matches product IDs with detailed information about each product such as nutrition facts, ingredients, etc. All with the latest information on each ingredient and links to further information.

Not So Different

In fact the concept of an RBP is not so foreign. Recently my local OfficeMax began offering refills for all ink cartridges. Refills have existed at restaurants as long as I’ve known.

While many of today’s containers are recyclable, recycling is not nearly as good as reusing and reducing. Recycling takes energy, and many of the things that you put into your recycling bin don’t actually get recycled for one reason or another. It does not really tackle the core issue.

Instead of creating and shipping millions of little bottles, companies could send entire vats of refillable goop all over the world. The RBP model is not just a giant win for the planet, it’s a boon for consumers and producers alike, as it would drive down the cost of production and therefore the cost of products.

Challenges

There are certainly many questions that need to be addressed for such a world to become a reality. For example, the question of sanitation. How can you guarantee that a refilled product will be as fresh as a brand new one if the container has been opened? I’m sure that through various techniques and technologies such challenges can be overcome. Perhaps each major reseller can have its own mini-sanitizing doo-hickey that cleans the insides of containers. Like all engineering problems, the solutions are out there as long as someone is willing to put in the effort.

Think it’s a good idea? Pass it on. 🙂