Subversion's locking feature is currently limited to files
only—it's not yet possible to reserve access to a whole
directory tree.
In the Subversion repository, a
lock is a piece of metadata which
grants exclusive access to one user to change a file. This
user is said to be the lock owner.
Each lock also has a unique identifier, typically a long
string of characters, known as the lock
token. The repository manages locks in a separate
table, and enforces locks during a commit operation. If any
commit transaction attempts to modify or delete the file (or
delete a parent of the file), the repository will demand two
pieces of information:
-
User
authentication
. The client performing the commit
must be authenticated as the lock owner.
-
Software
authorization
. The user's working copy must send
the lock token with the commit, proving that it knows
exactly which lock it's using.
An example is in order, to demonstrate. Let's say that
Harry has decided to change a JPEG image. To prevent other
people from committing changes to the file, he locks the file
in the repository using the
svn lock
command:
$ svn lock banana.jpg --message "Editing file for tomorrow's release."
'banana.jpg' locked by user 'harry'.
$ svn status
K banana.jpg
$ svn info banana.jpg
Path: banana.jpg
Name: banana.jpg
URL: https://svn.example.com/repos/project/banana.jpg
Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
Revision: 2198
Node Kind: file
Schedule: normal
Last Changed Author: frank
Last Changed Rev: 1950
Last Changed Date: 2005-03-15 12:43:04 -0600 (Tue, 15 Mar 2005)
Text Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005)
Properties Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005)
Checksum: 3b110d3b10638f5d1f4fe0f436a5a2a5
Lock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e
Lock Owner: harry
Lock Created: 2005-06-14 17:20:31 -0500 (Tue, 14 Jun 2005)
Lock Comment (1 line):
Editing file for tomorrow's release.
There are a number of new things demonstrated in the
previous example. First, notice that Harry passed the
--message
option to
svn
lock
. Similar to
svn commit
,
the
svn lock
command can take comments
(either via
--message (-m)
or --file
(-F)
) to describe the reason for locking the file.
Unlike
svn commit
, however,
svn
lock
will not demand a message by launching your
preferred text editor. Lock comments are optional, but still
recommended to aid communication.
Second, the lock attempt succeeded. This means that the
file wasn't already locked, and that Harry had the latest
version of the file. If Harry's working copy of the file had
been out-of-date, the repository would have rejected the
request, forcing harry to
svn update
and
reattempt the locking command.
Also notice that after creating the lock in the
repository, the working copy has cached information about the
lock—most importantly, the lock token. The presence of
the lock token is critical. It gives the working copy
authorization to make use of the lock later on. The
svn status
command shows a
K
next to the file (short for locKed),
indicating that the lock token is present.
Now that Harry has locked banana.jpg
,
Sally is unable to change or delete that file:
$ whoami
sally
$ svn delete banana.jpg
D banana.jpg
$ svn commit -m "Delete useless file."
Deleting banana.jpg
svn: Commit failed (details follow):
svn: DELETE of
'/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg':
423 Locked (https://svn.example.com)
But Harry, after touching up the banana's shade of yellow,
is able to commit his changes to the file. That's because he
authenticates as the lock owner, and also because his working
copy holds the correct lock token:
$ whoami
harry
$ svn status
M K banana.jpg
$ svn commit -m "Make banana more yellow"
Sending banana.jpg
Transmitting file data .
Committed revision 2201.
$ svn status
$
Notice that after the commit is finished,
svn
status
shows that the lock token is no longer
present in working copy. This is the standard behavior
of
svn commit
: it walks the working copy
(or list of targets, if you provide such a list), and sends
all lock tokens it encounters to the server as part of the
commit transaction. After the commit completes
successfully, all of the repository locks that were
mentioned are released—
even on files that
weren't committed.
The rationale here is to
discourage users from being sloppy about locking, or from
holding locks for too long. For example, suppose Harry were
to haphazardly lock thirty files in a directory named
images
, because he's unsure of which
files he needs to change. He ends up making changes to only
four files. When he runs
svn commit
images
, the process would still release all thirty
locks.
This behavior of automatically releasing locks can be
overridden with the --no-unlock
option
to
svn commit
. This is best used for
those times when you want to commit changes, but still plan
to make more changes and thus need to retain existing locks.
This behavior is also semi-permanently tweakable, by setting
no-unlock = yes
in your run-time
config
file (see
the section called “Runtime Configuration Area”).
Of course, locking a file doesn't oblige one to commit a
change to it. The lock can be released at any time with a
simple
svn unlock
command:
$ svn unlock banana.c
'banana.c' unlocked.