A design for locking.
---------------------
(...in progress, based on ongoing discussions on dev@ list.
Please hack on this.)
A "lock" means a (possibly shared) write-lock on a file or directory.
When a file or directory is locked, only the lock-holder(s) may commit
a change to it.
- In the case of files, "commit a change" means changing a file's
text or props, deleting it, or moving it.
- In the case of directories, "commit a change" means changing the
directory's props or entries-list, deleting it, or moving it.
This also applies recursively, to all child directories & files.
[How about depth-0 directory locks? The use-case is to protect
dir props only; useful since those are not merged. --brane]
Repository Implementation:
--------------------------
* Implement in libsvn_repos, not libsvn_fs. Just like the hooks
feature, locking is an external system overlaid on top of a
versioning filesystem.
- Create new pre- and post- lock/unlock commit hooks.
- Have svn_repos_fs_commit_txn() enforce locking.
* Locks table
Location and implementation of this table is still being discussed.
-----------------
Various options for client-side behavior. Drop brainstorms here.
Most of this discussion is based on stuff happening in IRC, which will
be refined and brought to the dev@ list.
Goals:
- client must allow user to lock/unlock paths.
- want to prevent the user from wasting time on an unmergeable change.
Framework:
- the client will have 'svn lock/unlock' commands.
- a lock-token's is an object whose most important fields are a
UUID and username.
* Justification for lock-tokens: the svn client doesn't always
know who you are. Not all repository connections are
authenticated (for example, typically not read operations),
so it's too error-prone to identify locks purely by
username. Instead, we identify locks by uniquely named
lock-tokens. Hence the UUID.
* (still being discussed) We may want to include a 'comment'
field which shows users why a file was locked. (who/where/why).
- 'svn lock' returns a lock-token to the client, then stored in the WC.
If the connection is unauthenticated, then the lock creation fails.
In other words, we don't allow "anonymous" locks.
- 'svn commit' notices the lock-token on a committable object, and
sends it when building the repository transaction. (The server
requires the token, along with matching authn, to allow the path
to be changed.)
- 'svn unlock' also requires authentication (but not a token). If
successful, the lock is removed from the path.
Still being discussed: perhaps 'svn unlock' requires token
and authn, while 'svn unlock --force' requires only authn.
- need to extend 'svn status' to include locked objects in its
standard display of "interesting things." (Additionally, 'svn st
-u' probably needs to show objects locked in the repository,
along with lock comments if --verbose is used.)
UI interaction models:
- The latest client UI proposal.
Mark certain files with a special svn: property which means
"this file cannot be changed except when locked." Files with
this property would be read-only in the working copy most of
the time for most users. 'svn lock' makes the file editable,
which means users get habitutated to the command, and thus are
more likely to discover pre-existing locks before starting
unmergeable work.
Note that you can still 'svn lock' any file you want. The
special property isn't required, it's just a way of helping
people remember that a file is unmergeable.
[I suggest that this should be a read-only liveprop whose
value is implied by server-side configuration, and can't
be modified by the client. This is a repository policy,
not a user decision. -- brane]
Weird scenarios with lock-tokens/working-copies:
- Every lock has exactly one lock-token.
User locks a file, gets a lock-token. This token now lives in
this single working copy. If the user wants to "control" the
file from a different working copy, then she must
- 'svn unlock file' (from anywhere; only requires authn)
- re-lock the file in the 2nd working copy.
This generates a new lock, and thus a new lock-token (new UUID),
stored in the 2nd working copy.
* Probably want to implement 'svn relock' or 'svn lock
--force' to "steal" an existing lock.
* Question: what about the first working copy? It still
thinks it has a lock, but that lock doesn't even exist
anymore. It's been destroyed. What's the mechanism for the
working copy to learn this and toss its dead lock-token?
- Branko thinks 'svn up' should report lock tokens, and
should remove stale locks as a sort of conflict.