Design for new lock extension

Martin Geisler mg at aragost.com
Tue Mar 22 06:23:59 CDT 2011


Hi guys,

My client want me to write an extension that will allow them to lock
files that cannot be merged easily. We'll make the extension public and
so we would like input from you guys.

I've put the design here:

  http://mercurial.selenic.com/wiki/LockExtension/NewDesign

and you can comment on it inline below:


  1. Introduction

Mercurial is not well suited for development that involves (binary)
files that cannot be merged. One example is specification development
using tools such as Framemaker or Word. Parallel versions of files occur
naturally in Mercurial, so in trying to prevent this, we are "going
against the grain". At the same time, introducing a different tool like
Subversion is obviously not very attractive.

2. Lock workflow

The crucial thing is that users stay up to date with changes from others
by pulling from the central team repository often and pushing as soon as
modifications are done. The workflow looks like this:

    * Pull from team repository and update to latest revision.

    * Lock files to be modified. Do not modify files locked by someone
      else!

    * Modify and commit.

    * Push to team repository. The extension automatically unlocks files
      when push occurs.

As an exception, locks can be "stolen" or unlocks can be "forced" (e.g.
someone went on holiday and left a file locked). Modifications to a
previous revision are allowed as long as a separate named branch is used
(e.g. to do a bug-fix release). If the team follows this workflow,
(unintended) parallel versions will rarely occur --- only when a lock is
stolen or unlock forced. The project can specify which for which files
locking is mandatory. Other files can also be locked.

3. Lock Extension

The proposed design for the lock extension follows.

3.1. Clarifications

    * The "lock repository" is the repository in which lock information
      is stored. This is typically the project's central repository,
      which is shared by the work repositories.

    * A file is said to be "up to date" in a work repository if there is
      no later revision on the same branch including it in the lock
      repository.

3.2. Configuration

    * The lock repository location can be defined in a configuration
      file as default-lock in the [paths] section. If the location is
      not defined, the default path is used. If the lock repository
      cannot be found or it contains no lock information, lock
      operations fail with an appropriate message.

    * File patterns can be defined in a controlled file in the
      repository root directory called .hglock. The syntax is as for
      .hgignore. If a file in the repository matches a pattern in this
      file, locking is mandatory. If a file does not match any pattern,
      locking is optional.

4. Commands

Note: Some commands can take multiple files as argument. The operation
is not expected to be atomic (that is, 'hg lock', for example, can lock
some files and fail to lock others). The command fails overall if the
operation fails for an least one file. We ignore this complication in
the description of the commands.

    * 'hg locks': List the locks in the lock repository. The fields and
      order are: user email, branch, how long the file has been locked,
      last commit time, path.

    * 'hg lock FILE': If the file is unmodified, up to date and not
      locked, lock the file. Otherwise, fail with an appropriate
      message.

    * 'hg lock FILE --steal': If the file is unmodified, up to date and
      locked by someone else, transfer the lock to the user and send an
      email notifying the original user. Otherwise, fail with an
      appropriate message.

    * 'hg unlock FILE': If the file is unmodified and locked by the
      user, unlock the file. Otherwise, fail with an appropriate
      message.

    * 'hg unlock FILE --force': If the file is locked by someone else,
      unlock the file and send an email notifying the original user.
      Otherwise, fail with an appropriate message.

    * 'hg commit': Ignores modified, unlocked files for which locking is
      mandatory; outputs a warning message for each such file. Operates
      like normal on other files. The lock is refreshed in the lock
      repository for each locked file that was part of the commit.

    * 'hg push': Unlocks locked files that are part of the revisions to
      be pushed.

    * 'hg update': New versions of files are handled as follows:

          o modified, unlocked files for which locking is mandatory:
            Local versions are overwritten by other versions using the
            internal:other merge tool and listed as such in the output.

          o modified, locked files: Other versions are created using the
            internal:dump merge tool. Then the user resolves. (This case
            should only occur if a lock has been stolen or an unlock
            forced. Otherwise the lock policy ensures that merges of
            files for which locking is mandatory are trivial.)

          o All other files are handled as normal.

Please let me know your thoughts!

-- 
Martin Geisler

aragost Trifork
Professional Mercurial support
http://aragost.com/en/services/mercurial/blog/


More information about the Mercurial-devel mailing list