blob: f0c8d7440740e62b4e1242440e7bdbdf5c29bfeb [file] [log] [blame]
A UI Specification for "Locking"
This document describes a user interface of a new locking system for
Subversion. It implements the set of features described in the
associated functional spec.
I. Introduction
A. Goals/Audience
There are two audiences we need to consider for a locking UI:
1. The enlightened software developer
- understands general VC concepts (required for job)
- understands concurrency model
- has already embraced Subversion (or at least CVS)
- ITCH: Some files aren't mergeable, like image files or
spreadsheets. Need to force serialized edits on such
things, as an occasional exception to concurrency.
2. The reluctant user of version control
- bright people, but no time or interest in learning VC concepts
- doesn't understand concurrency
- doesn't understand "out-of-dateness" or merging procedures
- typical examples:
- coder who has only used VSS or Clearcase with 100% locking
- website developer being forced to use VC
- manager being forced to use VC
- ITCH: VC system should be effortless, transparent, and
idiot proof. VC system should prevent people from
wasting editing time, destroying each others
changes, all while avoiding concurrency concepts such
as "merging" and "out of dateness".
B. The "Hijack" Scenario
This is specific use-case which is particularly important to
making version control usable by the second type of user
described above.
In this scenario, the user has a tool that circumvents whatever
system is in place to enforce serialized editing. In systems
like VSS or Clearcase 'copy' views, this usually means an
editor that ignores the read-only attribute on a file. When
the user goes to commit, they discover that they were supposed
to lock the file, and the repository version has changed. What
now?
The power-svn user would certainly have no problem knowing what
to do seeing an error that "the file must be locked to commit",
nor would such a user be confused by seeing a subsequent error
that the "file is out-of-date". The power user would run 'svn
update', resolve conflicts, then lock the file and commit.
But the reluctant or ignorant svn user shouldn't (and doesn't
need to) be forced to deal with merging and out-of-dateness
when working in an "all locking" environment. Here are a few
usability case-studies:
- Clearcase dynamic views
The workspace is always up-to-date, all of the time. And
it's impossible to circumvent the read-only bit. So the
hijack scenario can't happen at all.
- Clearcase copy-based views
In the hijack scenario, the user attempts to commit and
the client responds by attempting an interactive
contextual merge. If not possible, the whole commit
fails and a guru is phoned to fix the situation.
- Visual Source Safe
in the hijack scenario, the user remembers to lock the
file long after editing it; VSS asks whether to use the
server version or local version of the file. Somebody's
edits are lost.
It is the recommendation of this document that the command line
client produce normal conflicts when 'svn up' is run on a
hijacked file; but that for a GUI such as TortoiseSVN, a more
friendly (or interactive) procedure is followed -- perhaps one
that allows the user to choose between versions of files.
II. New Client Behaviors
A. Overview
This section describes a user interface to accomplish "locking",
as described in the functional spec. A new property is used to
enforce locking and prevent people from wasting time; lock
tokens are objects, stored in the working copy, that represent a
lock; and two new subcommands (lock/unlock) are described.
B. The "svn:needs-lock" property
Create a new "svn:needs-lock" property to indicate that a file
should be locked before committing. Just like "svn:executable",
the value of the property is irrelevant and the property can be
created (or deleted) by any user or administrator.
Note that this property doesn't enforce locking.
When the Subversion client encounters the "svn:needs-lock"
property on a path (on checkout or update), it sets the
working-copy path to a read-only state by default. This
serves as a reminder to the user that she should lock this
path before editing it. When a user locks the path, the
Subversion client makes the working-copy path read-write.
When the user releases the lock, or if the lock is found to
be defunct (see next section), the Subversion client makes
the path read-only again.
C. Lock manipulation via client
1. Lock Tokens
When a user successfully locks a path, the working copy
receives a "lock token" from the server. This token is an
object that connects your exclusive right to commit to a path
with your working copy.
You can think of a lock token as a form of authentication for
a certain working copy. Why is it important or useful for
lock tokens to be attached to only one working copy?
[An example: you might lock an unmergeable file using a
computer at your office, perhaps as part of a changeset in
progress. It should not be possible for a working copy on
your home computer to accidentally commit a change to that
same file, just because you've authenticated as the user
which owns the lock. If you really want to change the file
from home, you'd have to "steal" the lock from your other
working copy, which is discussed later in this document.]
Because locks can be broken or stolen, it is possible for a
lock token to become "defunct". A defunct lock cannot be
used or released--it is useless and is cleaned up when you
next run 'svn update'.
2. New client subcommands
Summary:
svn lock [--force]: lock (or steal)
svn unlock [--force]: release (or break)
a. Creating a lock
To lock a path, use the 'svn lock' command:
$ svn lock foo.c
username: harry
password: XXXXX
[...]
'foo.c' locked by user 'harry'.
In order for this command to work,
- You *must* provide a username to the server.
'anonymous' locks are not allowed.
- The path must not already be locked.
- The path must not be out-of-date.
The lock command accepts -m or -F to add a lock comment, so
others can see why the file was locked. The lock comment
is optional.
b. Using a lock
A lock can be used to make an exclusive commit to a path.
Also, if you have a lock, you can opt to "release"
(destroy) it when you're done.
To make use of a lock, two forms of authentication must be
provided to the server:
- The authenticated username that owns the lock
- A non-defunct lock token
If either of these forms of authentication are missing or
incorrect, the lock cannot be used.
1. Using a lock to Commit
$ svn commit foo.c
Upon successful commit, a locked path is released by
default. The Subversion client provides an option to
retain the lock after commit:
$ svn commit foo.c --no-unlock
If --no-unlock is not specified, even unmodified files
will be considered part of the commit and shown to the
user in the list of files to commit. Such files will
also be unlocked after the commit.
2. Releasing a lock
$ svn unlock foo.c
Lock on 'foo.c' has been released.
After successful release, the working copy's lock token
is gone.
c. Breaking a lock
"Breaking" a lock is a means of releasing a lock when:
- The authenticated username is not the same as the
lock owner, or
- The working-copy lock representation is unavailable.
Use the --force option to the unlock subcommand to
break a lock. For example:
$ svn unlock foo.c
username: sally
password: XXXX
svn: error: 'foo.c' is locked by user 'harry'.
$ svn unlock foo.c --force
username: sally
password: XXXX
Lock on 'foo.c' has been broken.
The --force option also accepts a URL, so that the lock
can be
released without a working copy.
d. Stealing a lock
"Stealing" a lock is a means of creating a lock when:
- The path is locked by you, but you don't have a
representation of the lock in your current working
copy, or
- The path is locked by someone else.
In order to steal a lock, a user must be authenticated to
the server.
Use the --force option to the lock command to steal a
lock. For example:
$ svn lock foo.c
username: sally
password: XXXX
svn: error: 'foo.c' is locked by user 'harry'.
$ svn lock foo.c --force
username: sally
password: XXXX
'foo.c' locked by user 'sally'.
Remember that the 'svn lock' command still requires that the
target be up-to-date to succeed.
e. Discovering/examining locks
1. seeing lock tokens in a working copy
'svn status' considers a lock token "interesting", and
displays it using some new symbol, in a new column:
$ svn status
M foo.c
M K bar.c
A baz.c
Note that K (locKed) is used instead of the more
intuitive L, since L is already in use for another purpose.
2. seeing locks in a repository.
'svn status -u' adds out-of-date information from the
server; in a similar manner, this command shows any
locks that exist on the server:
$ svn status -u
M foo.c
M K bar.c
A * baz.c
* file1
O file2
M B file3
M T file42
As with "svn status", the sixth column indicates lock
state. The letters have the following meanings:
' ': No lock in either WC or repository.
'K': Locked in the WC and lock token valid in
repository.
'O': No lock in WC, lock in repository. (Locked in
Other WC.)
'B': Lock in WC, but no lock in repository. (Lock
Broken.)
'T': Locked in WC, but locked with another token in
repository. (Lock was sTolen.)
3. 'svn info', describes the attributes of a lock-token,
if attached to a working object. If invoked on a URL,
it displays information about any remote lock
attached.
$ svn info foo.c
Path: foo.c
Name: foo.c
URL: http://..../
[...]
Lock Token: 465610b1-33eb-0310-8a02-cae41507c13a
Lock Owner: lundblad
Lock Comment: Refactoring.
Lock Creation Date: 2004-12-14 14:49:36 +0100 (Tue, 14 Dec 2004)
$ svn info http://host/repos/file2
Path: /file2
Name: file2
URL: http://..../
[...]
Lock Token: 465610b1-33eb-0310-8a02-cae41507c13b
Lock Owner: fitz
Lock Comment: Don't touch my file!
Lock Creation Date: 2004-12-25 14:49:36 +0100 (Tue, 14 Dec 2004)
4. 'svn update' changes
At the start of an update, the client reports any
lock-tokens to the server. If a lock token has become
"defunct", the client is instructed to destroy the lock
token.
A new column will be added to the update output to indicate
removed lock tokens:
svn up
U path1
U path2
B path3
C B path4
In the above example, lock tokens for path3 and path4
were removed. Note that 'B' is used even if there is
a new lock in the repository.
III. New Server Behaviors
A. Overview
This section describes new server UIs for locking: two new hook
scripts, a new 'svnlook' subcommand, and a new 'svnadmin' subcommand.
B. Tracking locks
The Subversion server holds the master list of all locks for a
repository. It responds to client requests to create, release,
break and steal locks.
C. Enforcement
During a commit, the server checks for locks the same way that
it checks for out-of-dateness:
$ svn commit
Sending foo.c
Sending bar.c
svn: error: 'bar.c' is locked by user 'harry'.
D. Configurable Mechanisms
1. New "pre-" hook scripts
a. pre-lock
Used to authorize lock creation. Invoked whenever a user
creates a lock ('svn lock') or steals a lock ('svn lock
--force'). If an administrator wants the locking feature
completely disabled, just set this hook to always return failure.
- input: REPOS, PATH, USER
- successful exit means lock is allowed, else deny lock creation.
- if path is already locked, hook script can deduce
that USER is "stealing" the lock and decide what to do.
b. pre-unlock
Used to authorize lock releasing. Invoked whenever a user
releases a lock ('svn unlock) or breaks a lock ('svn
unlock' --force).
- input: REPOS, PATH, USER
- successful exit means release is allowed, else deny.
- if path is already locked, hook script can deduce
that USER is "breaking" the lock and decide what to do.
2. New "post-" hook scripts
a. post-lock
Used to report lock creation. Invoked whenever a user
creates a lock ('svn lock') or steals a lock ('svn lock
--force').
- input: REPOS, PATH, USER
- exit code ignored
- can be used to send email, collect statistics, etc.
b. post-unlock
Used to report lock release. Invoked whenever a user
releases a lock ('svn unlock') or breaks a lock ('svn unlock
--force').
- input: REPOS, PATH, USER
- exit code ignored
- can be used to send email, collect statistics, etc.
E. Lock manipulation with svnadmin
1. Discovering locks
A new 'svnlook listlocks' subcommand shows all current locks
in a repository:
$ svnlook listlocks /usr/local/svn/repos
# harry Aug 16 15:13 /trunk/bar.c
# sally Sep 07 09:30 /trunk/doc/foo.doc
2. Unconditional release of locks
A new 'svnadmin unlock' subcommand to unconditionally
release a lock. Note that this command circumvents hook
scripts, much like other svnadmin actions:
$ svnadmin unlock /usr/local/svn/repos /trunk/doc/foo.doc
Lock on '/trunk/doc/foo.doc' has been released.