Mercurial, Migration Assistant, and dotfiles
I recently upgraded my iMac. Migration Assistant moved all of my files to the new machine without issue -- or so it seemed.
I had created Mercurial repositories in a couple of virtualenv environments, to track changes locally.[1] I didn't notice that Mercurial had put each virtual environment's .Python file under revision control.
Shortly after completing the migration I made changes in one of these virtual environments. A quick 'hg status' before committing, and...
$ hg status
abort: data/.Python.i@13b27e856c38: no match found!
WTF?
After much investigation it appears that the following has happened.
- Mercurial represented the .Python link in its .hg/store/data directory as ._Python.i
- The leading underscore appears to be Mercurial's way of noting that the 'P' should be capitalized.
- I think Migration Assistant uses ditto to copy files.
- ditto saw the leading '._' and concluded this was an orphaned resource file.[2] So it didn't copy the file.
- Mercurial knew that it was supposed to have a .hg/store/data/._Python.i file; when it couldn't find it, it decided the repository was corrupted.
Luckily the problem cropped up before I traded in the old machine, so I was able to copy across the missing files manually.
In my experiments, the problem manifested only when the capitalized dotfile was a symbolic link, not when it was a regular data file.
Well... the above write-up contains several unproven assertions, e.g. about the conditions under which Mercurial will create a '._' filename. I'm not really sure whether this is a bug or merely a caveat regarding an obscure corner condition. For now, the easiest workaround is:
Don't Track virtualenv .Python Files With Mercurial.
[Update 2010/02/22: Someone has already filed this as a Mercurial bug.]
[1] (Mercurial makes a great filesystem "undo" facility, useful even for directory trees which you never intend to share with anyone else.)
[2] OS X still supports something ike resource forks. In tarballs and other non-OS Extended filesystems, resource forks are represented as dot-files with a leading underscore. (See Norman Walsh's blog for more info.) For example, the resource fork for a file named 'foo.txt' might be '._foo.txt'.