Mercurial is designed to handle concurrent access. You can have
- a single
hg push
operation (a write operation) and
- multiple
hg pull
and hg clone
operations (read operations)
simultaneously. In other words, readers don't have to wait on each other and they also don't have to wait for a single writer. Writers have to wait for other writers.
As pehrs note, this is done with locks. However, it's not done by locking the files themselves with file-system locks. Instead, a lock file is created.
The lock file is a symbolic link on systems that support it, and a normal file on other systems. The file or symlink contains the hostname and the process identifier (PID) of the process that acquired the lock. This is used to detect stale locks: if the process that acquired the lock is no longer alive, then we can safely break the lock.
The above ensures that only one process writes data to a given repository at a time. However, there are more dangers when using network file systems. One potential problem is that
$ hg clone foo bar
creates hard links between foo
and bar
. This is done to save space and greatly speed up the clone operation. If a new commit is made in bar
, Mercurial will carefully break the hard links before writing new data into the files. It basically does
$ cp abc abc.tmp
$ rm abc
$ mv abc.tmp abc
to make sure that a file abc
is not shared with anybody else. This is only done if the link count for abc
is greater than 1. If the link count is 1, then it would be a big waste to first copy the file. Now, the problem is that some network file systems have been lying about the link count to Mercurial! They reported 1 when they should report 2 or more and this tricked Mercurial into not breaking hard links. Mercurial 1.6.3 has a bugfix for this case — Mercurial will now breaks the hard links unconditionally when writing to a network drive.
So, please make sure that you use a recent version of Mercurial for such a setup.