Today we experienced a new way in which Mercurial can fail you.  I'm not talking about performance, twisted workflows, etc.  This time we're talking about Mercurial being unable to handle things that you can put into your repository in one platform on others.  The TL;DR version is, don't rename directories by just changing the case of their name.  For the longer version, read on!

What happened was that Randell landed a code update for WebRTC today which included a seemingly innocent rename of a directory.  Specifically the changeset renamed media/webrtc/trunk/src/modules/audio_coding/codecs/iSAC to media/webrtc/trunk/src/modules/audio_coding/codecs/isac.  He had created that changeset on Linux, and everything worked perfectly fine, and then he pushed it to mozilla-inbound.  Soon after that we noticed that attempts to push Ed Morley noticed this error when performing a merge on Windows:

case-folding collision between media/webrtc/trunk/src/modules/audio_coding/codecs/iSAC/fix/source/filterbank_tables.c and media/webrtc/trunk/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c

I tried that on Mac, and indeed this issue happened there as well.  But Randell could not see this issue on Linux.  We soon decided that this was unacceptable and we had to take that changeset out of our history, so we closed the tree, ran hg strip on the server side, something that should only be done as a last (desperate) measure.  This is probably one other instance of the well known case folding problem in Mercurial, and many of such similar problems fixed before.  The underlying problem is caused by the fact that Mercurial stores directories with the same name as the real directory in the contents of your repository inside your repository store, so if you create changesets on a case-sensitive file system (the default on most Linux distros) then your repository will break on case-insensitive file systems (the default on Windows and Mac.)

I have reported this issue to Mercurial, and we'll see what it takes for it to get fixed.  This was a very negative experience today, and I hope that this post would be useful so that others would not run into the same problem that we did.  We ended up creating a push hook which rejects changesets which do this kind of thing to make sure that this does not happen again at Mozilla.