Kimmo’s Nest

WinMerge development and some personal thoughts.

Letting Mercurial help the development

Posted by kimmov on October 22, 2008

Past months I’ve been using Mercurial distributed version control system (DVCS) to help my WinMerge development tasks. I can honestly say I couldn’t implement some stuff for WinMerge without using Mercurial. And I’m currently very much dependent on it for my WinMerge development.

This does not mean that we’ll convert WinMerge project to use Mercurial in near future. Subversion (SVN) isĀ  good as a central source repository for WinMerge. SourceForge supports it and lately SourceForge’s SVN has became faster too. I don’t mind people publishing their work as Mercurial repositories, I can even pull patches from those repositories. But SourceForge’s SVN remains the official place for the sources.

I strongly recommend people to try Mercurial as a personal tool. As Mercurial and Subversion work pretty well together. The magic is in using hgsvn for converting subversion repository to Mercurial repository. And then getting further changes from SVN to Mercurial. Oh, almost forgot to mention Mercurial has a TortoiseSVN kind of interface, TortoiseHG for Windows users.

The initial conversion of the (WinMerge) repository takes quite a lot of time, but after that the process is very smooth. To decrease the initial conversion time one can only get revisions from certain revision onwards. I’d recommend converting latest 2000-3000 revisions at max from WinMerge repository. For just development there isn’t anything really interesting in commits made years ago.

So lets assume we have the converted repository available. How to work with it efficiently and where is the magic?

The biggest thing is having concept called local commits. You can do so many (and so small) commits as you wish, you can do as many errors and reverts as you wish. Without fearing to cause some mess into the main repository. Basically the idea is to track your work as you do it in local repository. I personally do a new commit every few minutes, even if my code doesn’t compile I just commit it. Other way to see it is creating frequent checkpoints of your work. If you do an error (oops, that change is buggy!) then you just see what you did after latest commit and perhaps revert that work. That is, revert few lines of code, few minutes of work. Instead of hours or days of work. Or just fix the thing with new commit without revert.

Which brings the second big advantage of Mercurial. It is very fast! Doing a local commit takes less than second. So it always takes more time to write the commit message than the committing itself. With subversion every commit may take minutes to do. You really don’t want to commit often with SVN. With Mercurial the committing is just a natural thing, like saving a file in the editor. But you get the full history of your work.

My personal workflow is like this:

  1. update the local repository (using hgsvn) from SourceForge SVN repository
  2. create a clone of the repository for the work
  3. create a new branch into the new repository (I’ll explain the reason for branch below)
  4. develop the feature/fix in the branch, do a lots of commits until the code is “ready”
  5. create the patch by diffing the working branch and trunk (the SVN conversion) branches
  6. submit the patch to SourceForge.net

Sometimes the patch gets finished with one try. Sometimes there is a bug or something missing and I’ll need to continue developing it. Then I:

  1. update the trunk branch from SVN (to get latest commits)
  2. merge changes from trunk branch to working branch (Mercurial does this)
  3. continue developing the feature in working branch until it can be submitted to SourceForge.net again

This may needed to be repeated several times. But eventually it hopefully gets to the point when the changes are ready to be committed to SourceForge.net repository. The point in creating a working branch inside the repository is being able to easily see the changes between work in progress and the latest sources in SVN. Creating a patch is just one command. So the trunk branch in repository follows the official sources. Merging changes from SVN (trunk branch) to work branch makes sure you work against latest sources. Sometimes I don’t merge, especially if there are other changes to the code I’m working with.

So what if there is a bug or something still missing? Just repeat the steps above. Usually I’ll keep these working repositories around for some time. So if I need to continue work with the feature/patch I can first check how (and why) I ended up doing it the way I did it. Tens of small commits with good commit messages tell a lot more than one big SVN commit.

Merging is also one area where Mercurial shines. With CVS and SVN (and many other tools) merging is a task everybody is afraid of doing. It almost every time breaks something (if the merge isn’t trivial). Mercurial has advanced merge algorithm which itself handles lots of the merging work automatically. Sometimes it cannot determine what to do and then one can use some merge program (like WinMerge!) to do the merge. In DVCS tools the merging is very central action to do – it is routine. Not the flag-day action when all development stops until the resulting mess is sorted out.

There is no way I’m doing any bigger refactorings or changes for WinMerge without using Mercurial. There is some amount of work required to learn using the Mercurial and how to work with Mercurial and Subversion. But that is definitely worth of it.

Oh, and I know about Git. I’m using it too. It is a great tool, even faster than Mercurial. BUT it doesn’t natively support Windows (and WinMerge is Windows software). And I personally feel it is not so easy to use than Mercurial is.


Leave a Reply

You must be logged in to post a comment.