
                          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.
