awips2/pdf/NWS_Documentation/Subversion/1. 7 svn-book-html-chunk/svn.advanced.locking.html

728 lines
40 KiB
HTML
Raw Normal View History

2017-08-28 11:33:02 -06:00
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Locking</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2" />
<style type="text/css">
body { background-image: url('images/draft.png');
background-repeat: no-repeat;
background-position: top left;
/* The following properties make the watermark "fixed" on the page. */
/* I think that's just a bit too distracting for the reader... */
/* background-attachment: fixed; */
/* background-position: center center; */
}</style>
<link rel="home" href="index.html" title="Version Control with Subversion [DRAFT]" />
<link rel="up" href="svn.advanced.html" title="Chapter 3. Advanced Topics" />
<link rel="prev" href="svn.advanced.sparsedirs.html" title="Sparse Directories" />
<link rel="next" href="svn.advanced.externals.html" title="Externals Definitions" />
</head>
<body>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Locking</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="svn.advanced.sparsedirs.html">Prev</a> </td>
<th width="60%" align="center">Chapter 3. Advanced Topics</th>
<td width="20%" align="right"> <a accesskey="n" href="svn.advanced.externals.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="sect1" title="Locking">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="svn.advanced.locking"></a>Locking</h2>
</div>
</div>
</div>
<p>Subversion's copy-modify-merge version control model lives
and dies on its data merging algorithms—specifically on
how well those algorithms perform when trying to resolve
conflicts caused by multiple users modifying the same file
concurrently. Subversion itself provides only one such
algorithm: a three-way differencing algorithm that is smart
enough to handle data at a granularity of a single line of text.
Subversion also allows you to supplement its content merge
processing with external differencing utilities (as described in
<a class="xref" href="svn.advanced.externaldifftools.html#svn.advanced.externaldifftools.diff3" title="External diff3">the section called “External diff3”</a> and
<a class="xref" href="svn.advanced.externaldifftools.html#svn.advanced.externaldifftools.merge" title="External merge">the section called “External merge”</a>), some
of which may do an even better job, perhaps providing
granularity of a word or a single character of text. But common
among those algorithms is that they generally work only on text
files. The landscape starts to look pretty grim when you start
talking about content merges of nontextual file formats. And
when you can't find a tool that can handle that type of merging,
you begin to run into problems with the copy-modify-merge
model.</p>
<p>Let's look at a real-life example of where this model runs
aground. Harry and Sally are both graphic designers working on
the same project, a bit of marketing collateral for an
automobile mechanic. Central to the design of a particular
poster is an image of a car in need of some bodywork, stored in
a file using the PNG image format. The poster's layout is
almost finished, and both Harry and Sally are pleased with the
particular photo they chose for their damaged car—a baby
blue 1967 Ford Mustang with an unfortunate bit of crumpling on
the left front fender.</p>
<p>Now, as is common in graphic design work, there's a change
in plans, which causes the car's color to be a concern. So Sally
updates her working copy to <code class="literal">HEAD</code>, fires up
her photo-editing software, and sets about tweaking the image so
that the car is now cherry red. Meanwhile, Harry, feeling
particularly inspired that day, decides that the image would
have greater impact if the car also appears to have suffered
greater impact. He, too, updates to <code class="literal">HEAD</code>,
and then draws some cracks on the vehicle's windshield. He
manages to finish his work before Sally finishes hers, and after
admiring the fruits of his undeniable talent, he commits the
modified image. Shortly thereafter, Sally is finished with the
car's new finish and tries to commit her changes. But, as
expected, Subversion fails the commit, informing Sally that
her version of the image is now out of date.</p>
<p>Here's where the difficulty sets in. If Harry and Sally
were making changes to a text file, Sally would simply update
her working copy, receiving Harry's changes in the process. In
the worst possible case, they would have modified the same
region of the file, and Sally would have to work out by hand the
proper resolution to the conflict. But these aren't text
files—they are binary images. And while it's a simple
matter to describe what one would expect the results of this
content merge to be, there is precious little chance that any
software exists that is smart enough to examine the common
baseline image that each of these graphic artists worked
against, the changes that Harry made, and the changes that Sally
made, and then spit out an image of a busted-up red Mustang with
a cracked windshield!</p>
<p>Of course, things would have gone more smoothly if Harry and
Sally had serialized their modifications to the image—if,
say, Harry had waited to draw his windshield cracks on Sally's
now-red car, or if Sally had tweaked the color of a car whose
windshield was already cracked. As is discussed in
<a class="xref" href="svn.basic.version-control-basics.html#svn.basic.vsn-models.copy-merge" title="The copy-modify-merge solution">the section called “The copy-modify-merge solution”</a>, most of
these types of problems go away entirely where perfect
communication between Harry and Sally
exists.<sup>[<a id="idp34529920" href="#ftn.idp34529920" class="footnote">19</a>]</sup> But as one's version control
system is, in fact, one form of communication, it follows that
having that software facilitate the serialization of
nonparallelizable editing efforts is no bad thing. This is
where Subversion's implementation of the lock-modify-unlock
model steps into the spotlight. This is where we talk about
Subversion's <em class="firstterm">locking</em> feature, which is
similar to the <span class="quote"><span class="quote">reserved checkouts</span></span> mechanisms of
other version control systems.</p>
<p>Subversion's locking feature exists ultimately to minimize
wasted time and effort. By allowing a user to programmatically
claim the exclusive right to change a file in the repository,
that user can be reasonably confident that any energy he invests
on unmergeable changes won't be wasted—his commit of those
changes will succeed. Also, because Subversion communicates to
other users that serialization is in effect for a particular
versioned object, those users can reasonably expect that the
object is about to be changed by someone else. They, too, can
then avoid wasting their time and energy on unmergeable changes
that won't be committable due to eventual
out-of-dateness.</p>
<p>When referring to Subversion's locking feature, one is
actually talking about a fairly diverse collection of behaviors,
which include the ability to lock a versioned
file<sup>[<a id="idp34533792" href="#ftn.idp34533792" class="footnote">20</a>]</sup> (claiming the exclusive right to
modify the file), to unlock that file (yielding that exclusive
right to modify), to see reports about which files are locked
and by whom, to annotate files for which locking before editing
is strongly advised, and so on. In this section, we'll cover
all of these facets of the larger locking feature.</p>
<div class="sidebar" title="The Three Meanings of “Lock”">
<a id="svn.advanced.locking.meanings"></a>
<p class="title">
<b>The Three Meanings of <span class="quote"><span class="quote">Lock</span></span></b>
</p>
<p>In this section, and almost everywhere in this book, the
words <span class="quote"><span class="quote">lock</span></span> and <span class="quote"><span class="quote">locking</span></span> describe
a mechanism for mutual exclusion between users to avoid
clashing commits. Unfortunately, there are two other sorts
of <span class="quote"><span class="quote">lock</span></span> with which Subversion, and therefore
this book, sometimes needs to be concerned.</p>
<p>The second is <em class="firstterm">working copy locks</em>,
used internally by Subversion to prevent clashes between
multiple Subversion clients operating on the same working
copy. This is the sort of lock indicated by an
<code class="computeroutput">L</code> in the third column of
<span class="command"><strong>svn status</strong></span> output, and removed by the
<span class="command"><strong>svn cleanup</strong></span> command, as described in <a class="xref" href="svn.tour.cleanup.html" title="Sometimes You Just Need to Clean Up">the section called “Sometimes You Just Need to Clean Up”</a>.</p>
<p>Third, there are <em class="firstterm">database locks</em>,
used internally by the Berkeley DB backend to prevent clashes
between multiple programs trying to access the database. This
is the sort of lock whose unwanted persistence after an error
can cause a repository to be <span class="quote"><span class="quote">wedged,</span></span> as
described in <a class="xref" href="svn.reposadmin.maint.html#svn.reposadmin.maint.recovery" title="Berkeley DB Recovery">the section called “Berkeley DB Recovery”</a>.</p>
<p>You can generally forget about these other kinds of locks
until something goes wrong that requires you to care about
them. In this book, <span class="quote"><span class="quote">lock</span></span> means the first sort
unless the contrary is either clear from context or explicitly
stated.</p>
</div>
<div class="sect2" title="Creating Locks">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="svn.advanced.locking.creation"></a>Creating Locks</h3>
</div>
</div>
</div>
<p>In the Subversion repository, a
<em class="firstterm">lock</em> is a piece of metadata that
grants exclusive access to one user to change a file. This
user is said to be the <em class="firstterm">lock owner</em>.
Each lock also has a unique identifier, typically a long
string of characters, known as the <em class="firstterm">lock
token</em>. 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.</p>
<p>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 <span class="command"><strong>svn lock</strong></span> command.</p>
<div class="informalexample">
<pre class="screen">
$ svn lock banana.jpg -m "Editing file for tomorrow's release."
'banana.jpg' locked by user 'harry'.
$
</pre>
</div>
<p>The preceding example demonstrates a number of new things.
First, notice that Harry passed the
<code class="option">--message</code> (<code class="option">-m</code>) option to
<span class="command"><strong>svn lock</strong></span>. Similar to <span class="command"><strong>svn
commit</strong></span>, the <span class="command"><strong>svn lock</strong></span> command can
take comments—via either <code class="option">--message</code>
(<code class="option">-m</code>) or <code class="option">--file</code>
(<code class="option">-F</code>)—to describe the reason for locking the
file. Unlike <span class="command"><strong>svn commit</strong></span>, however,
<span class="command"><strong>svn lock</strong></span> will not demand a message by
launching your preferred text editor. Lock comments are
optional, but still recommended to aid communication.</p>
<p>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 <span class="command"><strong>svn update</strong></span> and
reattempt the locking command. The locking command would also
have failed if the file had already been locked by someone
else.</p>
<p>As you can see, the <span class="command"><strong>svn lock</strong></span> command
prints confirmation of the successful lock. At this point,
the fact that the file is locked becomes apparent in the
output of the <span class="command"><strong>svn status</strong></span> and <span class="command"><strong>svn
info</strong></span> reporting subcommands.</p>
<div class="informalexample">
<pre class="screen">
$ 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.
$
</pre>
</div>
<p>The fact that the <span class="command"><strong>svn info</strong></span> 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 <span class="command"><strong>svn status</strong></span>
command shows a <code class="literal">K</code> next to the file (short
for locKed), indicating that the lock token is present.</p>
<div class="sidebar" title="Regarding Lock Tokens">
<p class="title">
<b>Regarding Lock Tokens</b>
</p>
<p>A lock token isn't an authentication token, so much as
an <span class="emphasis"><em>authorization</em></span> token. The token
isn't a protected secret. In fact, a lock's unique token is
discoverable by anyone who runs <strong class="userinput"><code>svn info
<em class="replaceable"><code>URL</code></em></code></strong>. A lock token is
special only when it lives inside a working copy. It's
proof that the lock was created in that particular working
copy, and not somewhere else by some other client. Merely
authenticating as the lock owner isn't enough to prevent
accidents.</p>
<p>For example, suppose you lock a file using a computer at
your office, but leave work for the day before you finish
your changes to that file. It should not be possible to
accidentally commit changes to that same file from your home
computer later that evening simply because you've
authenticated as the lock's owner. In other words, the lock
token prevents one piece of Subversion-related software from
undermining the work of another. (In our example, if you
really need to change the file from an alternative working
copy, you would need to <em class="firstterm">break</em> the
lock and relock the file.)</p>
</div>
<p>Now that Harry has locked <code class="filename">banana.jpg</code>,
Sally is unable to change or delete that file:</p>
<div class="informalexample">
<pre class="screen">
$ 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'
$
</pre>
</div>
<p>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:</p>
<div class="informalexample">
<pre class="screen">
$ svn status
M K banana.jpg
$ svn commit -m "Make banana more yellow"
Sending banana.jpg
Transmitting file data .
Committed revision 2201.
$ svn status
$
</pre>
</div>
<p>Notice that after the commit is finished, <span class="command"><strong>svn
status</strong></span> shows that the lock token is no longer
present in the working copy. This is the standard behavior of
<span class="command"><strong>svn commit</strong></span>—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—<span class="emphasis"><em>even on files that weren't
committed</em></span>. 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
<code class="filename">images</code> because he's unsure of which files
he needs to change, yet changes only four of those files, when he
runs <strong class="userinput"><code>svn commit images</code></strong>, the process will
still release all 30 locks.</p>
<p>This behavior of automatically releasing locks can be
overridden with the <code class="option">--no-unlock</code> option to
<span class="command"><strong>svn commit</strong></span>. 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
<code class="literal">no-unlock</code> runtime configuration option (see
<a class="xref" href="svn.advanced.confarea.html" title="Runtime Configuration Area">the section called “Runtime Configuration Area”</a>).</p>
<p>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 <span class="command"><strong>svn unlock</strong></span> command:</p>
<div class="informalexample">
<pre class="screen">
$ svn unlock banana.c
'banana.c' unlocked.
</pre>
</div>
</div>
<div class="sect2" title="Discovering Locks">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="svn.advanced.locking.discovery"></a>Discovering Locks</h3>
</div>
</div>
</div>
<p>When a commit fails due to someone else's locks, it's
fairly easy to learn about them. The easiest way is to run
<strong class="userinput"><code>svn status -u</code></strong>:</p>
<div class="informalexample">
<pre class="screen">
$ svn status -u
M 23 bar.c
M O 32 raisin.jpg
* 72 foo.h
Status against revision: 105
$
</pre>
</div>
<p>In this example, Sally can see not only that her copy of
<code class="filename">foo.h</code> is out of date, but also that one of the
two modified files she plans to commit is locked in the
repository. The <code class="literal">O</code> symbol stands for
<span class="quote"><span class="quote">Other,</span></span> meaning that a lock exists on the file
and was created by somebody else. If she were to attempt a
commit, the lock on <code class="filename">raisin.jpg</code> would
prevent it. Sally is left wondering who made the lock, when,
and why. Once again, <span class="command"><strong>svn info</strong></span> has the
answers:</p>
<div class="informalexample">
<pre class="screen">
$ svn info http://svn.example.com/repos/project/raisin.jpg
Path: raisin.jpg
Name: raisin.jpg
URL: http://svn.example.com/repos/project/raisin.jpg
Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec
Revision: 105
Node Kind: file
Last Changed Author: sally
Last Changed Rev: 32
Last Changed Date: 2006-01-25 12:43:04 -0600 (Sun, 25 Jan 2006)
Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
Lock Owner: harry
Lock Created: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)
Lock Comment (1 line):
Need to make a quick tweak to this image.
$
</pre>
</div>
<p>Just as you can use <span class="command"><strong>svn info</strong></span> to examine
objects in the working copy, you can also use it to examine
objects in the repository. If the main argument to
<span class="command"><strong>svn info</strong></span> is a working copy path, then all
of the working copy's cached information is displayed; any
mention of a lock means that the working copy is holding a
lock token (if a file is locked by another user or in another
working copy, <span class="command"><strong>svn info</strong></span> on a working copy
path will show no lock information at all). If the main
argument to <span class="command"><strong>svn info</strong></span> is a URL, the
information reflects the latest version of an object in the
repository, and any mention of a lock describes the current
lock on the object.</p>
<p>So in this particular example, Sally can see that Harry
locked the file on February 16 to <span class="quote"><span class="quote">make a quick
tweak.</span></span> It being June, she suspects that he probably
forgot all about the lock. She might phone Harry to complain
and ask him to release the lock. If he's unavailable, she
might try to forcibly break the lock herself or ask an
administrator to do so.</p>
</div>
<div class="sect2" title="Breaking and Stealing Locks">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="svn.advanced.locking.break-steal"></a>Breaking and Stealing Locks</h3>
</div>
</div>
</div>
<p>A repository lock isn't sacred—in Subversion's
default configuration state, locks can be released not only by
the person who created them, but by anyone. When somebody
other than the original lock creator destroys a lock, we refer
to this as <em class="firstterm">breaking the lock</em>.</p>
<p>From the administrator's chair, it's simple to break
locks. The <span class="command"><strong>svnlook</strong></span>
and <span class="command"><strong>svnadmin</strong></span> programs have the ability to
display and remove locks directly from the repository. (For
more information about these tools, see
<a class="xref" href="svn.reposadmin.maint.html#svn.reposadmin.maint.tk" title="An Administrator's Toolkit">the section called “An Administrator's Toolkit”</a>.)</p>
<div class="informalexample">
<pre class="screen">
$ svnadmin lslocks /var/svn/repos
Path: /project2/images/banana.jpg
UUID Token: opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923
Owner: frank
Created: 2006-06-15 13:29:18 -0500 (Thu, 15 Jun 2006)
Expires:
Comment (1 line):
Still improving the yellow color.
Path: /project/raisin.jpg
UUID Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
Owner: harry
Created: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)
Expires:
Comment (1 line):
Need to make a quick tweak to this image.
$ svnadmin rmlocks /var/svn/repos /project/raisin.jpg
Removed lock on '/project/raisin.jpg'.
$
</pre>
</div>
<p>The more interesting option is to allow users to break
each other's locks over the network. To do this, Sally simply
needs to pass the <code class="option">--force</code> to the <span class="command"><strong>svn
unlock</strong></span> command:</p>
<div class="informalexample">
<pre class="screen">
$ svn status -u
M 23 bar.c
M O 32 raisin.jpg
* 72 foo.h
Status against revision: 105
$ svn unlock raisin.jpg
svn: 'raisin.jpg' is not locked in this working copy
$ svn info raisin.jpg | grep URL
URL: http://svn.example.com/repos/project/raisin.jpg
$ svn unlock http://svn.example.com/repos/project/raisin.jpg
svn: Unlock request failed: 403 Forbidden (http://svn.example.com)
$ svn unlock --force http://svn.example.com/repos/project/raisin.jpg
'raisin.jpg' unlocked.
$
</pre>
</div>
<p>Now, Sally's initial attempt to unlock failed because she
ran <span class="command"><strong>svn unlock</strong></span> directly on her working copy
of the file, and no lock token was present. To remove the
lock directly from the repository, she needs to pass a URL
to <span class="command"><strong>svn unlock</strong></span>. Her first attempt to unlock
the URL fails, because she can't authenticate as the lock
owner (nor does she have the lock token). But when she
passes <code class="option">--force</code>, the authentication and
authorization requirements are ignored, and the remote lock is
broken.</p>
<p>Simply breaking a lock may not be enough. In
the running example, Sally may not only want to break Harry's
long-forgotten lock, but relock the file for her own use.
She can accomplish this by using <span class="command"><strong>svn unlock</strong></span>
with <code class="option">--force</code> and then <span class="command"><strong>svn lock</strong></span>
back-to-back, but there's a small chance that somebody else
might lock the file between the two commands. The simpler thing
to do is to <em class="firstterm">steal</em> the lock, which involves
breaking and relocking the file all in one atomic step. To
do this, Sally passes the <code class="option">--force</code> option
to <span class="command"><strong>svn lock</strong></span>:</p>
<div class="informalexample">
<pre class="screen">
$ svn lock raisin.jpg
svn: Lock request failed: 423 Locked (http://svn.example.com)
$ svn lock --force raisin.jpg
'raisin.jpg' locked by user 'sally'.
$
</pre>
</div>
<p>In any case, whether the lock is broken or stolen, Harry
may be in for a surprise. Harry's working copy still contains
the original lock token, but that lock no longer exists. The
lock token is said to be <em class="firstterm">defunct</em>. The
lock represented by the lock token has either been broken (no
longer in the repository) or stolen (replaced with a
different lock). Either way, Harry can see this by asking
<span class="command"><strong>svn status</strong></span> to contact the
repository:</p>
<div class="informalexample">
<pre class="screen">
$ svn status
K raisin.jpg
$ svn status -u
B 32 raisin.jpg
Status against revision: 105
$ svn update
Updating '.':
B raisin.jpg
Updated to revision 105.
$ svn status
$
</pre>
</div>
<p>If the repository lock was broken, then <strong class="userinput"><code>svn
status --show-updates</code></strong> (<code class="option">-u</code>)
displays a <code class="literal">B</code> (Broken) symbol next to the
file. If a new lock exists in place of the old one, then a
<code class="literal">T</code> (sTolen) symbol is shown. Finally,
<span class="command"><strong>svn update</strong></span> notices any defunct lock tokens
and removes them from the working copy.</p>
<div class="sidebar" title="Locking Policies">
<p class="title">
<b>Locking Policies</b>
</p>
<p>Different systems have different notions of how strict a
lock should be. Some folks argue that locks must be
strictly enforced at all costs, releasable only by the
original creator or administrator. They argue that if
anyone can break a lock, chaos runs rampant and the
whole point of locking is defeated. The other side argues
that locks are first and foremost a communication tool. If
users are constantly breaking each other's locks, it
represents a cultural failure within the team and the
problem falls outside the scope of software enforcement.</p>
<p>Subversion defaults to the <span class="quote"><span class="quote">softer</span></span>
approach, but still allows administrators to create stricter
enforcement policies through the use of hook scripts. In
particular, the <code class="filename">pre-lock</code> and
<code class="filename">pre-unlock</code> hooks allow administrators
to decide when lock creation and lock releases are allowed
to happen. Depending on whether a lock already exists,
these two hooks can decide whether to allow a certain user
to break or steal a lock. The
<code class="filename">post-lock</code> and
<code class="filename">post-unlock</code> hooks are also available,
and can be used to send email after locking actions. To
learn more about repository hooks, see <a class="xref" href="svn.reposadmin.create.html#svn.reposadmin.create.hooks" title="Implementing Repository Hooks">the section called “Implementing Repository Hooks”</a>.</p>
</div>
</div>
<div class="sect2" title="Lock Communication">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="svn.advanced.locking.lock-communication"></a>Lock Communication</h3>
</div>
</div>
</div>
<p>We've seen how <span class="command"><strong>svn lock</strong></span>
and <span class="command"><strong>svn unlock</strong></span> can be used to create,
release, break, and steal locks. This satisfies the goal of
serializing commit access to a file. But what about the
larger problem of preventing wasted time?</p>
<p>For example, suppose Harry locks an image file and then
begins editing it. Meanwhile, miles away, Sally wants to do
the same thing. She doesn't think to run <strong class="userinput"><code>svn status
-u</code></strong>, so she has no idea that Harry has
already locked the file. She spends hours editing the file,
and when she tries to commit her change, she discovers that
either the file is locked or that she's out of date.
Regardless, her changes aren't mergeable with Harry's. One of
these two people has to throw away his or her work, and a lot of
time has been wasted.</p>
<p>Subversion's solution to this problem is to provide a
mechanism to remind users that a file ought to be locked
<span class="emphasis"><em>before</em></span> the editing begins. The mechanism
is a special property: <code class="literal">svn:needs-lock</code>. If
that property is attached to a file (regardless of its value,
which is irrelevant), Subversion will try to use
filesystem-level permissions to make the file read-only—unless,
of course, the user has explicitly locked the file.
When a lock token is present (as a result of using
<span class="command"><strong>svn lock</strong></span>), the file becomes read/write.
When the lock is released, the file becomes read-only
again.</p>
<p>The theory, then, is that if the image file has this
property attached, Sally would immediately notice
something is strange when she opens the file for editing:
many applications alert users immediately when a read-only
file is opened for editing, and nearly all would
prevent her from saving changes to the file. This
reminds her to lock the file before editing, whereby she
discovers the preexisting lock:</p>
<div class="informalexample">
<pre class="screen">
$ /usr/local/bin/gimp raisin.jpg
gimp: error: file is read-only!
$ ls -l raisin.jpg
-r--r--r-- 1 sally sally 215589 Jun 8 19:23 raisin.jpg
$ svn lock raisin.jpg
svn: Lock request failed: 423 Locked (http://svn.example.com)
$ svn info http://svn.example.com/repos/project/raisin.jpg | grep Lock
Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b
Lock Owner: harry
Lock Created: 2006-06-08 07:29:18 -0500 (Thu, 08 June 2006)
Lock Comment (1 line):
Making some tweaks. Locking for the next two hours.
$
</pre>
</div>
<div class="tip" title="Tip" style="margin-left: 0.5in; margin-right: 0.5in;">
<table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25">
<img alt="[Tip]" src="images/tip.png" />
</td>
<th align="left">Tip</th>
</tr>
<tr>
<td align="left" valign="top">
<p>Users and administrators alike are encouraged to attach
the <code class="literal">svn:needs-lock</code> property to any file
that cannot be contextually merged. This is the primary
technique for encouraging good locking habits and preventing
wasted effort.</p>
</td>
</tr>
</table>
</div>
<p>Note that this property is a communication tool that
works independently from the locking system. In other words,
any file can be locked, whether or not this property is
present. And conversely, the presence of this property
doesn't make the repository require a lock when
committing.</p>
<p>Unfortunately, the system isn't flawless. It's possible
that even when a file has the property, the read-only reminder
won't always work. Sometimes applications misbehave and
<span class="quote"><span class="quote">hijack</span></span> the read-only file, silently allowing
users to edit and save the file anyway. There's not much that
Subversion can do in this situation—at the end of the
day, there's simply no substitution for good interpersonal
communication.<sup>[<a id="idp34643696" href="#ftn.idp34643696" class="footnote">21</a>]</sup></p>
</div>
<div class="footnotes">
<br />
<hr width="100" align="left" />
<div class="footnote">
<p><sup>[<a id="ftn.idp34529920" href="#idp34529920" class="para">19</a>] </sup>Communication wouldn't have been such bad
medicine for Harry and Sally's Hollywood namesakes, either, for
that matter.</p>
</div>
<div class="footnote">
<p><sup>[<a id="ftn.idp34533792" href="#idp34533792" class="para">20</a>] </sup>Subversion does not currently allow locks on
directories.</p>
</div>
<div class="footnote">
<p><sup>[<a id="ftn.idp34643696" href="#idp34643696" class="para">21</a>] </sup>Except, perhaps, a classic
Vulcan mind-meld.</p>
</div>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="svn.advanced.sparsedirs.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="svn.advanced.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="svn.advanced.externals.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Sparse Directories </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Externals Definitions</td>
</tr>
</table>
</div>
<div xmlns="" id="svn-footer">
<hr />
<p>You are reading <em>Version Control with Subversion</em> (for Subversion 1.7), by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.<br />
This work is licensed under the <a href="http://creativecommons.org/licenses/by/2.0/">Creative Commons Attribution License v2.0</a>.<br />
To submit comments, corrections, or other contributions to the text, please visit <a href="http://www.svnbook.com/">http://www.svnbook.com/</a>.</p>
</div>
</body>
</html>