i-think Twenty-Two

Now with more coherency.

Mercurial: Taming Multiple Heads with Bookmarks

| Comments

I’m a huge fan of version control. I have fond memories of first learning Subversion and setting up a source control server. I also remember the pain involved every time I wanted to create a new repository. Sure, I had a good process and it wasn’t that bad, but it was still something. For a long time I really thought that nothing could be better. Then I was introduced to this:

$ hg init .

That one line changed my life forever. Pretty soon I had just about everything I was actively working on managed by source control. It truly was a golden age. At this time I was generally working inside my own repositories sheltered from the rest of the world. Even for a single user Mercurial came to my aid by protecting me from myself. Coupled with an awesome diff tool I felt unstoppable. I was able to better break down problems and experiment more knowing that I could easily get back to a known good state and easily examine exactly what I’d just changed.

Of course as these things go it was only a matter of time before I was able to really dive into a repository that was actively maintained by other users. Here I was finally able to see if Mercurial was worthy of all the hype that I had read having consumed plenty of documentation (and forgetting all the things I wasn’t using on a regular basis).

And I was generally happy. But one thing continued to niggle at me. The number of “Merge” commits seemed extremely unnecessary. So I looked into the rebase extension. Now I was able to graft my changes at the end of everyone else’s history. Most of my changes were fairly isolated and there were rarely any conflicts (and when there were easily resolved with a simple three way merge).

And so again, life was good. But as time moved on I became wary of all this rewriting of history. One instance of sending duplicate changesets to the ‘master’ repository will quickly identify how easy it is to do the wrong thing. Wasn’t Mercurial supposed to save me from all this? I lost faith and began to look elsewhere, learnt the ins and outs of Git and really came to like the light weight branching it offered. This seemed to be perfect for what I wanted. I could have feature branches on bits of work that I might do and then merge them into the trunk when I’m done. Suddenly the merges didn’t seem so bad as each served a specific purpose of bringing a feature to the main line.

So I looked into Mercurial branches. Branches in Mercurial aren’t as lightweight as in Git. And even when they are closed traces of them seem to last forever. That might be fine for some cases, but for the work I was doing I didn’t want to worry about coming up with unique names for my branches and have those choices persisted for all eternity.

So I went for a search to find how other Mercurial users tackle this apparent shortfall. The answer was to maintain multiple heads and to use bookmarks to manage each head.

When I was first learning about Mercurial I suppose I gave myself the impression that multiple heads were bad and whenever there was more than one head you need to merge. This is of course completely wrong.

Mercurial quite happily chugs along with multiple heads and indeed it is fairly fundamental to how it works. When it comes time to push your changes you might run into issues, but even here we can work around them.

How I use bookmarks to manage multiple heads

When you have multiple heads to work with it becomes evident fairly quickly that you will need to have a good way to switch between these heads. This is where bookmarks come into play. So let’s look at an example of how this works:

I’ve opened up my trusty console window and have updated my repository.

$ hg pull -u

I’ve used the -u switch here to update the repository at the same time as pulling the latest changes. I don’t have any bookmarks set yet so I’m going to create one now so that I can easily track the ‘tip’ from the ‘master’ repository. I’m going to call it ‘master’ because that’s easy to remember.

$ hg book master

I’ve shortened the bookmarks command to book because book is easier to type and still gets the point across without being too cryptic. Now I’m going to start working on a fairly major change. I want to be able to commit often as I know that I will get things into a partially working state frequently but don’t want to share my changes until I’m completely done. So I’ll create a new bookmark to keep track of these changes:

$ hg book batman

So now I have two bookmarks that both point to the same changeset. Importantly the active bookmark is batman because it’s the last bookmark I used. You can only have one active bookmark at a time. To see the bookmarks that I have I can just run the book command with no parameters.

$ hg book
 * batman               34:7f6c4f9e45fb
   master               34:7f6c4f9e45fb

Looks good. The * indicates which bookmark is currently active. Note that they both point to the same changeset. Now I’m going to make some changes and commit:

$ hg commit -m "Improved grapple."

Now if I look at my bookmarks I’ll see that batman has moved with my new changeset and master has stayed put.

$ hg book
 * batman               35:63a4549bc962
   master               34:7f6c4f9e45fb

This is generally the point where someone might interrupt me with an urgent change. This time I know it is a simple change and we need to get it into the master ASAP. I don’t want to risk my improved grapple though and this change is unrelated anyway so I’ll start back at the master bookmark.

$ hg update master
1 file updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg book robin
$ hg book
   batman               35:63a4549bc962
   master               34:7f6c4f9e45fb
 * robin                34:7f6c4f9e45fb

Now I can make my change and commit.

$ hg commit -m "Reduce brightness of Robin costume."
$ hg book
   batman               35:63a4549bc962
   master               34:7f6c4f9e45fb
 * robin                36:9832ab432fec

Now I can see that the robin bookmark has moved, the batman bookmark stays in place and the master bookmark still points to the last changeset I pulled from the master repository. At this point I technically have two heads.

$ hg heads .
changeset:   35:63a4549bc962
bookmark:    batman
user:        Rhys Parry <rhys@example.com>
date:        Wed Apr 3 20:40:12 2013 +1000
summary:     Improved grapple.

changeset:  36:9832ab432fec
bookmark:   robin
tag:        tip
user:       Rhys Parry <rhys@example.com>
date:       Wed Apr 3 20:52:19 2013 +1000
summary:    Reduce brightness of Robin costume.

Because we have bookmarks for these changesets we can quickly switch between them. Here you can also see that the robin changeset also is regarded as the tip of the repository. Because this change is urgent I want to push it to the master repository ASAP. So first I’ll check if there is anything new in the master repository.

$ hg in
comparing with B:\Batcave
searching for changes
changeset:   37: f33b6a00e172
tag:         tip
user:        Alfred Pennyworth <alfred@example.com>
date:        Wed Apr 3 20:38:19 2013 +1000
summary:     Improve delivery of hot cocoa.

Here we can see that there has been a change since I started working. If I want to push this change I’ll need to merge my changes. But first I’ll make updating as simple as possible.

$ hg update master
1 file updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg pull -u

This will pull in Alfred’s changes and leave us with three heads. Importantly when we used hg update master Mercurial knew we were switching to a bookmark so it set it as the active bookmark. When we pulled in Alfred’s changes the bookmark followed the update so now master is pointing where we were expecting it to.

$ hg book
   batman               35:63a4549bc962
 * master               37:f33b6a00e172
   robin                36:9832ab432fec

Now we just need to merge the robin branch into master and we’ll be in a position to start pushing our changes. Again, this is straightforward.

$ hg merge robin
$ hg commit -m "Merge Robin costume improvements."

This time I can easily come up with a merge message because I know that there is a common theme to what I am merging. The same would apply if I was merging one hundred changesets. I can also now think of the merge as a true change and not just a nasty side effect of my choice of version control system. Finally I am ready to push my changes to the master repository. Because I don’t want the changes from my batman bookmark going up I’ll take a bit more care and do the following:

$ hg push -r master

This will push the master bookmark and all its descendants (which now includes the robin changes as well but not the batman changes). If you want to preview what changesets you will be sending to the master repository you can always run the following command first:

$ hg out -r master

Sometimes you might forget to include the -r flag. If you do Mercurial will kindly refuse your push and none of your changes will be pushed. By default Mercurial isn’t keen on letting you push extra heads to other repositories.

With this in mind we can feel a little safer knowing that Mercurial will prevent us from inflicting our unfinished changes on others before their time. We can of course force these changes if we want:

$ hg push --force -B master -B batman backup

Here I’ve forced these extra heads to be pushed to my own backup repository so that if my machine fails all my changes, including the bookmarks (which are not pushed by default).

So that’s a peak at one of the ways I use Mercurial on a daily basis. I’m sure there are many improvements to the way I am currently working and I relish the opportunity to explore more of Mercurial’s functionality.

More thoughts on Google+

| Comments

So it seems as though I forgot a couple of points in last night’s blog post (First Impressions of Google+).

I should be able to sort my circles

While you can create new circles there doesn’t appear to be any way to sort them. Unfortunately this means that my extreme circles (close friends and fringe) are right next to each other and that’s just not right. However the problem really becomes evident with the menu list of your streams. Only your first custom circle is shown in the list (when you have added more than two custom circles). These are also sorted alphabetically after the predefined circles, which is a little odd, but I can see why it might be the case.

Preliminary conclusion

I think that at least in my case, Google+ is more likely to displace Twitter than Facebook. That said I’m not overly active on Facebook, but I find using twitter is a great way to keep up to date with the people I actually care about and a little industry stuff as well. I think Google+ is well targeted for that particular purpose. Like Twitter though you only know who is actually listening, not how much they care about what you say.

First Impressions of Google+

| Comments

Well, I managed to get on to Google+ today. My first impression is it feels like the love child of Facebook and Twitter. It may look a lot like Facebook when you are viewing your ‘Streams’, but the model feels much more like how Twitter would be if you could tweet to specific groups of people. I won’t bore you with the details of Circles and how they work, instead I’ll point out the things I really like and the missing features that I hope are filled in soon.

The Stream

Well, this is all pretty standard. So all the things from your circles that your circle friends have deemed you worthy to see appear here. What I would like to see here is the ability to exclude feeds from certain circles from appearing in the stream. This would allow your default view to be void of noise but still provide ready access to these people.

Circles and Sets

I have no doubt that this is a feature the guys at Google are keen to push out (the math nerds that they are). Basically what is needed is the ability to define composite circles, that is circles that use standard set operations (union, intersection and subtraction) to define their members. Of course they would have to explain it better than me, but some Venn diagrams should make it clear enough to just about anybody.

Suggestions that are smarter about multiple email addresses

Because the suggestions are based partly on the entire contents of you Gmail address book I’ve found that I get suggestions for people I’ve already added (but have multiple email accounts). One suggestion was even to add myself. Where I’ve told Google that I have multiple addresses I would hope that it could prune some of that for me.

I do like the multiple personality approach that Google+ gives you. I’m glad that even though set functionality isn’t available yet that by using circles you can model some pretty complex social hierarchies. Whether enough people will make the switch remains to be seen. I’m not holding my breath, because unless Google rapidly expands their trial interest may just fizzle. So, hopefully Google can bring wave after wave of improvements while the buzz is still in the air.

The Pipe Character '|' on Windows Phone 7

| Comments

Recently I decided to put a bit of Powershell in a reply to a tweet. I was using my fancy shmancy new Windows Phone 7. Well, needless to say I ran into a few problems when I tried to insert the pipe character. I suppose it isn’t too commonly used, but I really wanted it to get my message across (whilst I could have probably used a capital I to get my point across, some fonts won’t do that and it wouldn’t be able to be pasted, so that wouldn’t do).

After holding down what felt like every button ((On the English (UK) keyboard)) to see what special characters they revealed (like the iPhone, the ° symbol is hidden under the ‘0’ key) the pipe character still eluded me. However Windows Phone 7 also comes with a special smiley keyboard which has a wide array of smileys to choose from, including the flat :| smiley. Knowing that was the pipe character right there it became easy, simply insert the :| smiley, move the cursor between the colon and the pipe, hit the backspace key and move the cursor back to the end of the line.

It couldn’t be simpler…

Actually, maybe it could. Pipe symbol please!?!

Installing multiple MSI files using msiexec.exe and Powershell

| Comments

I use Powershell scripts to update test environments and when I can I prefer to use the MSI files that we would ship to a customer rather than hacking together an xcopy deployment. Recently I worked on a script that did the following:

  1. Check if an MSI already exists in a folder I designated as holding the current installation files (I called it ‘Current’).
  2. If the MSI exists, execute the uninstall process for the MSI, and remove the MSI from the ‘Current’ folder.
  3. Copy the new installation file from the build drop folder and put it in the ‘Current’ folder.
  4. Execute the install process on the MSI in the ‘Current’ folder.

However I soon ran into a problem in that when I called msiexec.exe it would not block the script, so it would try to run multiple instances on Windows Installer and if you’ve had any experience with Windows Installer you know that just doesn’t work (and for good reason).

A quick search on the interwebs revealed that I could simply wait for the msiexec.exe process to finish. Rather than doing some sort of convoluted monitoring of the process inside Powershell I decided to use the the Start-Process commandlet (inspired by Heath Stewart’s post ‘Waiting for msiexec to Finish’).

Start-Process is a little bit different from ‘start’ especially in how it passes the parameters (through the -ArgumentList argument/parameter). But fortunately the -Wait parameter was exactly what I was looking for. Here’s the final line:

Start-Process -FilePath msiexec -ArgumentList /i, $installer, /quiet -Wait

This let everything nicely chain together and now deployments are super easy, as they should be.