Correcting a deficiency in Mercurial handling of corrupt repositories

Date: Fri Apr 25 2014 Mercurial

Mercurial has an astonishing flaw. If a repository becomes corrupt, you can still push changes from that repository to/from other repositories and the corruption spreads to those other repositories. This is like a bad science fiction movie with a virus spreading to eat the whole world. Look through the mercurial mailing list to see the number of emails about corrupt repositories.

I've been astonished that this can happen... it seems clear to me that most of mercurials commands should do hg verify and if the verify fails then abort the request. Or they should use some other strategy to prevent doing transactions on a corrupted repository. I think a corrupted repository should be locked and unusable for most purposes.

I'm not sure of all the ways a repository can be corrupted. However one way is to go into the .hg/store directory of a repository and delete or modify the "*.i" files.

After some reading of chapter 10 of the unofficial mercurial book I came up with a method.

Put the following in the workspace .hg/hgrc file.

preoutgoing.verify = hg verify

The preoutgoing hooks are executed before changesets are pushed to another repository. This causes "hg verify" to be run before this occurs, and if this fails the push will be aborted.

This hook has to be installed in every instance of the repository. Near as I can tell a freshly cloned repository does not have this hook, even if the hook definition exists in the source repository.

I tried a few alternatives but discovered the joys (?frustrations?) of locking. For example the following might be a good defensive move:

pretxnchangegroup.verify = hg verify

But I found this will lead to an infinite wait for the repository lock to clear.