In the Subversion repository, a lock is a piece of metadata that 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, ultimately handling their creation, enforcement, and removal. If any commit transaction attempts to modify or delete a locked file (or delete one of the parent directories of the file), the repository will demand two pieces of information—that the client performing the commit be authenticated as the lock owner, and that the lock token has been provided as part of the commit process as a form of proof that the client knows which lock it is using.
To demonstrate lock creation, let’s refer back to our example of multiple graphic designers working on the same binary image files. Harry has decided to change a JPEG image. To prevent other people from committing changes to the file while he is modifying it (as well as alerting them that he is about to change it), he locks the file in the repository using the svn lock command:
$ svn lock banana.jpg -m "Editing file for tomorrow's release." 'banana.jpg' locked by user 'harry'. $
The preceding example demonstrates a number of new things. First,
notice that Harry passed the --message
(-m
) option to svn lock. Similar
to svn commit, the svn lock command can take comments—via either
--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. The locking command would also have failed if the file had already been locked by someone else.
As you can see, the svn lock command prints confirmation of the successful lock. At this point, the fact that the file is locked becomes apparent in the output of the svn status and svn info reporting subcommands:
$ svn status K banana.jpg $ svn info banana.jpg Path: banana.jpg Name: banana.jpg URL: http://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: 2006-03-15 12:43:04 -0600 (Wed, 15 Mar 2006) Text Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006) Properties Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006) Checksum: 3b110d3b10638f5d1f4fe0f436a5a2a5 Lock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e Lock Owner: harry Lock Created: 2006-06-14 17:20:31 -0500 (Wed, 14 Jun 2006) Lock Comment (1 line): Editing file for tomorrow's release. $
The fact that the svn info
command, which does not contact the repository when run against
working copy paths, can display the lock token reveals an important
piece of information about those tokens: they are cached in the working
copy. The presence of the lock token is critical. It gives the working
copy authorization to make use of the lock later on. Also, 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:
$ svn delete banana.jpg D banana.jpg $ svn commit -m "Delete useless file." Deleting banana.jpg svn: Commit failed (details follow): svn: Server sent unexpected return value (423 Locked) in response to DELETE request for '/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/ banana.jpg' $
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:
$ 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 the working copy. This is the standard behavior of
svn commit—it searches the working
copy (or list of targets, if you provide such a list) for local
modifications and sends all the lock tokens it encounters during this
walk 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.
This is meant to discourage users from being sloppy about locking or
from holding locks for too long. If Harry haphazardly locks 30 files in
a directory named images because
he’s unsure of which files he needs to change, yet changes only four of
those files, when he runs svn commit images
, the
process will still release all 30 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 you still plan to make more changes
and thus need to retain existing locks. You can also make this your
default behavior by setting the no-unlock
runtime configuration option (see
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.