This section is from the "Version Control with Subversion" book, by Ben Collins-Sussman, Brian W. Fitzpatrick and C. Michael Pilato. Also available from Amazon: Version Control with Subversion.
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 sort of proof that 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'. $
There are a number of new things demonstrated in the
previous example. First, notice that Harry passed the
--message
(-m
) 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.
Secondly, 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: DELETE of '/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg': 423 Locked (http://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:
$ 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 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 4 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 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
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.