14

This is somewhat related to this question but is a different question.

We have a central Hg repository, served to users via SSH and mercurial-server. We have a number of Mac, Linux and Windows clients connecting to it.

It has happened twice now that one of the Windows users has corrupted their repository, then pushed back to the central one corrupting it. I want to write an incoming hook script on the central repository to prevent a transaction from being accepted if it will corrupt the central repo.

Although unfortunately I don't know enough about Mercurial to write such a script. Any possibility that someone else has come across this? Personally I'm not quite sure why hg doesn't do this by default.

bobinabottle
  • 569
  • 2
  • 7
  • 19
  • I've found a solution here: http://davidherron.com/blog/topics/745-correcting-deficiency-mercurial-handling-corrupt-repositories that would need to be done on all the clients. But if anyone has a better solution that can do done for the central repo itself that would be better. – bobinabottle Dec 07 '09 at 15:36
  • Please give us more details: what version of Mercurial are you using on the server and on each of the clients? – Martin Geisler Dec 21 '09 at 23:34
  • 2
    Also, it would be extremely useful for us (the Mercurial developers) if you could reproduce this. Please also report such issues to us directly via our mailinglist: http://mercurial.selenic.com/wiki/MailingLists or bug tracker: http://selenic.com/mercurial/bts That is much more productive than posting here :-) – Martin Geisler Dec 21 '09 at 23:38

4 Answers4

4

Recent versions of Mercurial (since 1.5) support validation of incoming data. Add

[server]
validate = True

to your server's hg config (either .hg/hgrc or the hgwebdir config should work fine) to have the server verify incoming data and refuse invalid pushes. The client will then see an error akin to:

remote: abort: missing file data for beta:dddc47b3ba30e54484720ce0f4f768a0f4b6efb9 - run hg verify

Hope that helps!

Martin Geisler
  • 1,271
  • 9
  • 23
durin42
  • 241
  • 1
  • 2
2

Maybe you should avoid pushing to repository altogether. With Mercurial and its distributed nature, everybody can have their branch, and when they feel they are ready, they tell you and you pull from them. No commit-access problems, no push that will break stuff...

This is at least an advice a friend of mine has given me, when I was migrating from SVN to Mercurial.

I don't know, if this is an option to you, but setting up a personal repository for everybody and then pull from the people you need might require less work, than trying to catch dangerous pushes.

Martin Geisler
  • 1,271
  • 9
  • 23
0

Could you not do the same thing as David Herron's Blog, but instead of doing it on prerouting, do it on the precommit hook on the central repo?

Ryan Gibbons
  • 998
  • 9
  • 20
  • Nope :-( I've tried that but it ends up in a deadlock. When a client attempts to push it reserves a lock on the repository. Running a 'hg verify' also requires a lock, so it ends up just waiting forever in an endless loop. – bobinabottle Dec 14 '09 at 11:45
  • Also, even if this did work on precommit, it would verify the repository, see that it is ok, then commit the changes that would corrupt it. Really I would need a hook to assess whether the incoming changes would corrupt the repos, if so roll back the transaction. So It would make more sense to be on the changegroup hook. – bobinabottle Dec 14 '09 at 11:55
  • (Using the changegroup hook still results in deadlocks) – bobinabottle Dec 14 '09 at 11:56
  • Interesting - the hooks seem to be python based. Do you know what is corrupting the repository? Is the same thing each time? – Ryan Gibbons Dec 14 '09 at 14:37
0

One possible alternative is to:

  1. Clone the repository AFTER the push.
  2. Verify it.
  3. If the respository is good, archive it as the latest good one
  4. If the respository is corrupted, raise an alarm
  5. On alarm, restore the lastest known good respository.

This solution is not what you required, but at least, you get a way to rollback your repository in case of corruption.