doc/file-conditions
author Paul Crowley <paul@lshift.net>
Tue, 13 Oct 2009 10:41:24 +0100
changeset 110 69596fffcf7d
parent 83 86ec1268d306
child 112 3035990989ee
permissions -rw-r--r--
Less canonicalisation, use os.path to check for dotfiles

FILE CONDITIONS

Read configuring-access before you read this.

mercurial-server supports file and branch conditions, which restrict an
operation depending on what files it modifies and what branch the work is on.
However, the way these conditions work is subtle and can be counterintuitive -
if you want to keep things simple, stick to user and repo conditions, and then
things are likely to work the way you would expect.

File and branch conditions are added to the conditions against which a rule
matches, just like user and repo conditions; they have this form:

    file=<globpattern> - file in the repo
    branch=<globpattern> - name of the branch

However, in order to understand what effect adding these conditions will have,
it helps to understand how and when these rules are applied.

The rules file is used to make four decisions:

- Whether to allow a repository to be created
- Whether to allow access to a repository
- Whether to allow a changeset on a particular branch at all
- Whether to allow a changeset to change a particular file

When the first two of these decisions are being made, nothing is known about
what files might be changed, and so all file conditions automatically succeed
for the purpose of such decisions. This means that doing tricky things with
file conditions can have counterintuitive consequences:

- You cannot limit read access to a subset of a repository with a "read" rule
and a file condition: any user who has access to a repository can read all of
it and its full history. Such a rule can only have the effect of masking a
later "write" rule, as in this example:

   read repo=specialrepo file=dontwritethis
   write repo=specialrepo

allows all users to read specialrepo, and to write to all files *except* that
any changeset which writes to "dontwritethis" will be rejected.

- For similar reasons, don't give "init" rules file conditions.

- Don't try to deny write access to a particular file on a particular branch -
a developer can write to the file on another branch and then merge it in.
Either deny all writes to the branch from that user, or allow them to write to
all the files they can write to on any branch. In other words, something like
this will have the intended effect:

  write user=docs/* branch=docs file=docs/*

But something like this will not have the intended effect; it will effectively
allow these users to write to any file on any branch, by writing it to "docs"
first:

  write user=docs/* branch=docs
  write user=docs/* file=docs/*
  read user=docs/*