Difference between revisions of "SVN Directory Lock"

From Noah.org
Jump to navigationJump to search
m
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Category: Engineering]]
 
[[Category: Engineering]]
[[Category: Svn]]
+
[[Category: SVN]]
  
SVN does not allow directories to be locked. You can lock individual files, but not
+
Often it is useful to lock an entire directory tree to be sure that it remains consistent during testing or build deployment. SVN does not allow directories to be locked. You can lock individual files, but not an entire directory tree. Fortunately, it's easy to add this feature using a simple pre-commit hook script on the server.
entire directory trees. The following pre-commit hook will allow for <em>advisory</em> directory locks. That is, a directory lock will prevent a commit, but anyone can set or clear a lock.
 
  
Often it is useful to lock an entire directory to be sure that it remains consistent during testing or deployment.
+
The following pre-commit hook script will allow <em>advisory</em> locks. That is, a lock will prevent a commit, but any user may set or clear any lock. A user must deliberately clear and commit lock before further commits to the tree are allowed. This is intended to prevent accidental commits, and to track who modified a lock and why.
  
This scripts requires that [[Pexpect]] be installed. This script does not use the pysvn library. The reason for this is because I got too frustrated with the fact that the stupid library would not install on Red Hat Enterprise 4. I could not get either the RPM nor the source to install properly. It was easier to install Pexpect and simply script the command-line svn tools.
+
Someone familiar with other version control systems might ask why we don't simply tag or branch the trunk in order to test or build a release. The answer is because Subversion makes this very expensive in terms of time and storage space. A branch or tag doubles the amount of storage required for the entire directory tree. It doubles this every single time you branch or tag. So a directory lock is a cheap alternative to ensure that a source tree remains consistent during a given period of time. Nobody said Subversion was a very good version control system.
 +
 
 +
This script requires that [[pexpect]] be installed. Pexpect is a standard Debian/Ubuntu/RedHat package. This script does '''not''' use the pysvn library. The reason for this is because I got frustrated that the stupid library would not install on Red Hat Enterprise 4. I could get neither the RPM nor the source to install. It was far easier to use just Pexpect to script the command-line svn tools, which is after all what scripts are for.
  
 
== How to Use ==
 
== How to Use ==
When you create a lock no one will be able to commit to the locked directory or to any directory below it. The lock script will, of course, detect if you are commiting commiting a delete operation of an existing lock and the script will allow it.
+
 
 +
To create a lock you just create and commit a lock '''property''' on a directory. After you commit the lock property no further commits will be allowed to the locked directory tree. The only exception is for any commit that deletes the lock itself. This is necessary to allow a directory to be unlocked.
  
 
=== Create a lock ===
 
=== Create a lock ===
To set a lock on a directory tree simply create a property on a directory called "lock":
+
 
  svn propset lock TRUE trunk/project_a
+
To set a lock on a directory tree simply create a property on a directory called '''lock'''. Then you must commit the property to make it take effect.
Note that the value of the lock can be anything. I set it to TRUE, but you could make it a message or comment if you want.
+
 
 +
<pre>
 +
svn propset lock TRUE trunk/project_a
 +
svn commit trunk/project_a
 +
</pre>
 +
 
 +
The lock script does not care what value the '''lock''' property is set to. The script only checks if the '''lock''' property exists or not. The example above set the '''lock''' property value to TRUE, but the value could have been a descriptive text message giving the reason for the lock. For example,
 +
 
 +
<pre>
 +
svn propset lock 'Locked for bug hunting. Ask the build engineer if you have questions.' trunk/project_a
 +
svn commit trunk/project_a
 +
</pre>
 +
 
 +
Others can then see the value of the lock for a description of why the lock was set.
 +
 
 +
<pre>
 +
$ svn propget lock trunk/project_a
 +
Locked for bug hunting. Ask the build engineer if you have questions.
 +
</pre>
 +
 
 +
Of course, you can and should also describe the reason for the lock when you commit the '''lock''' property when you set the lock.
 +
 
 
=== Delete a lock ===
 
=== Delete a lock ===
To remove a lock simply delete the property:
+
 
  svn propdel lock trunk/project_a
+
To remove a lock simply delete the lock property and then commit:
 +
 
 +
<pre>
 +
svn propdel lock trunk/project_a
 +
svn commit trunk/project_a
 +
</pre>
  
 
== Repository Installation ==
 
== Repository Installation ==
I put the svn_dir_lock.py in my hooks directory.
+
 
I add the folloing code to the pre-commit shell script:
+
#To install put the '''svn_dir_lock.py''' script in your server hooks directory. In this example, I use ''/home/svn/repository/hooks/''.
 +
#Add the following code to the '''pre-commit''' shell script. Note that you must update the LOCK_SCRIPT_PATH to point to the script your server hooks directory.
 +
 
 
<pre>
 
<pre>
 +
LOCK_SCRIPT_PATH="/home/svn/repository/hooks/svn_dir_lock.py"
 
SVNLOOK=/usr/bin/svnlook
 
SVNLOOK=/usr/bin/svnlook
 
REPOS="$1"
 
REPOS="$1"
 
TXN="$2"
 
TXN="$2"
python /home/svn/repository/hooks/svn_dir_lock.py -v "$TXN" "$REPOS" >&2
+
if ! python ${LOCK_SCRIPT_PATH} -v "$TXN" "$REPOS" >&2; then
EXIT_STATUS=$?
+
     echo "ERROR: Commit failed. Delete locks before you commit." >&2
if [ $EXIT_STATUS -ne 0 ]; then
 
     echo "Delete locks before you checkin." >&2
 
 
     exit 1
 
     exit 1
 
fi
 
fi
Line 36: Line 65:
  
 
== svn_dir_lock.py Source ==
 
== svn_dir_lock.py Source ==
<include src="/var/www/usr/local/apache2/htdocs/engineering/svn_dir_lock.py" highlight="python" />
+
 
 +
<include src="/home/noahspurrier/noah.org/engineering/src/python/svn_dir_lock.py" highlight="python" />

Latest revision as of 11:31, 5 October 2010


Often it is useful to lock an entire directory tree to be sure that it remains consistent during testing or build deployment. SVN does not allow directories to be locked. You can lock individual files, but not an entire directory tree. Fortunately, it's easy to add this feature using a simple pre-commit hook script on the server.

The following pre-commit hook script will allow advisory locks. That is, a lock will prevent a commit, but any user may set or clear any lock. A user must deliberately clear and commit lock before further commits to the tree are allowed. This is intended to prevent accidental commits, and to track who modified a lock and why.

Someone familiar with other version control systems might ask why we don't simply tag or branch the trunk in order to test or build a release. The answer is because Subversion makes this very expensive in terms of time and storage space. A branch or tag doubles the amount of storage required for the entire directory tree. It doubles this every single time you branch or tag. So a directory lock is a cheap alternative to ensure that a source tree remains consistent during a given period of time. Nobody said Subversion was a very good version control system.

This script requires that pexpect be installed. Pexpect is a standard Debian/Ubuntu/RedHat package. This script does not use the pysvn library. The reason for this is because I got frustrated that the stupid library would not install on Red Hat Enterprise 4. I could get neither the RPM nor the source to install. It was far easier to use just Pexpect to script the command-line svn tools, which is after all what scripts are for.

How to Use

To create a lock you just create and commit a lock property on a directory. After you commit the lock property no further commits will be allowed to the locked directory tree. The only exception is for any commit that deletes the lock itself. This is necessary to allow a directory to be unlocked.

Create a lock

To set a lock on a directory tree simply create a property on a directory called lock. Then you must commit the property to make it take effect.

svn propset lock TRUE trunk/project_a
svn commit trunk/project_a

The lock script does not care what value the lock property is set to. The script only checks if the lock property exists or not. The example above set the lock property value to TRUE, but the value could have been a descriptive text message giving the reason for the lock. For example,

svn propset lock 'Locked for bug hunting. Ask the build engineer if you have questions.' trunk/project_a
svn commit trunk/project_a

Others can then see the value of the lock for a description of why the lock was set.

$ svn propget lock trunk/project_a
Locked for bug hunting. Ask the build engineer if you have questions.

Of course, you can and should also describe the reason for the lock when you commit the lock property when you set the lock.

Delete a lock

To remove a lock simply delete the lock property and then commit:

svn propdel lock trunk/project_a
svn commit trunk/project_a

Repository Installation

  1. To install put the svn_dir_lock.py script in your server hooks directory. In this example, I use /home/svn/repository/hooks/.
  2. Add the following code to the pre-commit shell script. Note that you must update the LOCK_SCRIPT_PATH to point to the script your server hooks directory.
LOCK_SCRIPT_PATH="/home/svn/repository/hooks/svn_dir_lock.py"
SVNLOOK=/usr/bin/svnlook
REPOS="$1"
TXN="$2"
if ! python ${LOCK_SCRIPT_PATH} -v "$TXN" "$REPOS" >&2; then
    echo "ERROR: Commit failed. Delete locks before you commit." >&2
    exit 1
fi

svn_dir_lock.py Source

<include src="/home/noahspurrier/noah.org/engineering/src/python/svn_dir_lock.py" highlight="python" />