Recently I’ve had a number of friends telling me how fantastic Drop Box is for synchronising files and how they don’t understand that I don’t use it. Drop Box has one very good argument in its favour: you can use it to maintain an off-site backup of your data, so if your office burns down you still have your files. Still, I mostly use Mercurial for synchronising my files. In this post I’m going to share with you how I’ve optimised Mercurial for single-user projects.
Step 1: hg synchronise
I have a few mercurial repositories that I use for personal projects. I might work on them in various locations (at work, on my laptop, on my desktop). When I’m working on them I normally have Internet access, so I can pull and update, do some work, commit, and push. Then I can swap computers and repeat. But all that sounds like a lot of steps just to keep files synchronised.
So I’ve developed a mercurial extension which simplifies this process. You can download the tool at the bottom of this post (it’s licensed under GPL).
Basically, what you have to do is this:
hg synchronise
This will commit your changes, push them to the remote repository, then pull any changes and warn you if you need to merge. After running a synchronise, your repository and the remote repository should both be pretty much identical. So the work flow is synchronise, do some work, then synchronise again. Naturally, you can abbreviate “hg synchronise” to “hg sync”.
Step 1(b): But what about my commit message?
While this solution is simple, the drawback is that in this work flow you don’t get a chance to specify the commit message. So I’ve added a few more commands to mercurial.
hg workon "Fixing bugs"
This sets what you’re working on (on the local computer only), and any calls to “hg synchronise” will include this task in the commit message. This task will remain set until you change it with “hg workon <new task>” or set the task as complete, using another new command:
hg complete
Use “hg complete” when you’ve completed the current task. This will perform a commit with a message saying the task and that it’s complete (it will even commit if you’ve made no changes, just to make sure the complete message is in the log). It will then synchronise with the server.
Running “hg workon” with no task name will display the current task. The “hg workon” command also has an alias of “hg task”.
Step 2: Making it automatic
But since we’re writing scripts here, why not write a script to make all this automatic? Well I’ve done just that. The code at the bottom of this post includes a tool which does the following:
- Every 30 minutes, runs “hg synchronise” on all repositories listed in your ~/.hgrepos file; and
- Every minute, runs “hg upsync” on those repos—this will do the same as synchronise if you have local uncommitted changes, otherwise it will do nothing.
Cool, give me the code
The code for the extension and the automatic synchronisation script is all copyright Joshua D. Bartlett 2010, and is Licensed under the GNU GPL. You may only download the attached code under the terms of this license.
Download: Synchronise – mercurial extension