[PATCH] Preliminary locking solution
From: Stein Roger Skafløtten <srsmail_at_hotmail.com>
Date: 2004-07-31 13:41:23 CEST
Hi all,
The attached patch implements a preliminary solution for locking files
A main goal was to change as little as possible and be non-intrusive:
It would be nice to have this functionality in the API, but I realize
[My first attempt on the client was to create a cute little python script,
Usage
lock: Locks the file(s).
Use the --force option to aquire the lock even if the file is locked
With -v, also print lock tokens.
Valid options:
Sample output: "svn lock --username=gorilla *.*"
Successfully locked design.tiff
Sample, verbose output: "svn lock --force -verbose project.prj"
Successfully locked project.prj (lock-c3JzL3Rlt3QxLnR4dA---)
[You can see that this is in fact the lock token by doing a
--- unlock: Unlocks the file(s). usage: unlock [PATH] Unlocks the file(s). If a file is locked by another user, an error message will be shown. Valid options: --targets arg : pass contents of file ARG as additional args --username arg : specify a username ARG --password arg : specify a password ARG --no-auth-cache : do not cache authentication tokens --non-interactive : do no interactive prompting --config-dir arg : read user configuration files from directory ARG Sample output: "svn unlock *.*" Successfully unlocked subversion.gif Could not unlock air.ogg: The file is locked by 'mozart' Could not unlock productlist.pdf: Not a versioned resource Successfully unlocked design.tiff Successfully unlocked project.xls Successfully unlocked banjo-budget.xls --- Attempting to commit changes a file locked by someone else (the lock-related message is at the end of the entire commit error message): $svn ci -m="changed some stuff" test.doc Sending test.doc Transmitting file data .svn: Commit failed (details follow): svn: MERGE request failed on '/myrepos/gorilla' svn: 'pre-commit' hook failed with error output: pete has exclusively locked gorilla/test.doc OK, so it would be nice if the "Commit failed" message was customizable... Applying the patch ------------------ 1. Rebuild the client The patch adds locking capabilities to the command line client by introducing two sub commands (changed main.c / cl.h and added lock-cmd.c and unlock-cmd.c) 2. Install server hooks a) Make sure "lock-commit.py" and "lock-revprop-change.py" are executable. b) Change pre-revprop-change and post-revprop-change to call "lock-revprop-change.py" c) Change pre-commit to call "lock-commit.py" I've included sample hooks at the end of this mail. lock-commit.py -------------- Called from pre-commit to check if any of the CRUD'ed files are locked by another user. If so, the commit fails. Locks on moved/deleted files are removed; see script comments for details. lock-revprop-change.py ---------------------- Called from the pre-revprop-change and post-revprop-change hooks. When called from pre, the script checks whether or not the user can lock the file. In post, the script patches the lock token (removes FLAG - see below) and sets the locktoken revprop = username. Internals... how files get locked --------------------------------- The exclusive lock implementation features creative use of the revprops on revision 0. When a file is locked, a new revprop is created on rev 0 (called the lock tocken), and the value of that revprop is the user who locks the file. When the file is unlocked, the revprop is removed. Also, if the file is deleted/moved, any "dangling" locks will be removed upon commit. The revprop naming scheme is as follows: locktoken ::= FLAG "lock-" base64(path-in-repos) lockvalue ::= username FLAG ::= R | F | N where R means remove lock F means forced lock N means non-forced lock The flags are actually removed on the server side as they are just there to tell the hook scripts what to do. Initially I actually tried to use the propvalue for this, but a bug in pre-1.1 prevents pre-revprop-change hooks from reading the value (I wanted this patch to work with older servers.) Someone might want to add WebDAV LOCK support which requires (IIRC) a universally unique lock identifier. In that case, just add the repos-uuid to the lock token. The path is base64 encoded except that [\n,=,+] are all replaced with '-' in order to form valid revprop names. Sample hook scripts ------------------- 1. pre-commit # check if any of the changed files are locked by another user /.../hook-scripts/lock-commit.py "$REPOS" "$TXN" || exit 1 exit 0 2. pre-revprop-change # we only allow lock and log prop's to be changed (change as you see fit) if [ "$PROPNAME" = "svn:log" ]; then exit 0; fi if [ "${PROPNAME:1:5}" != "lock-" ]; then exit 1; fi # check whether or not the file can be locked /.../hook-scripts/lock-revprop-change.py pre "$REPOS" "$PROPNAME" "$USER" || exit 1 exit 0 3. post-revprop-change # patches propval to contain username -or- removes the revprop if the FLAG is 'R' /.../hook-scripts/lock-revprop-change.py post "$REPOS" "$PROPNAME" "$USER" || exit 1 exit 0 Future enhancements (?) ----------------------- a) Make svn up/svn lock set non-mergable files read-only and have 'svn lock' make them readable. b) 'svn st' could perhaps show lock status... or is that mixing unrelated information? c) 'svnadmin' should be able to list and remove all locks in a repository (simple) d) Implement all the clever ideas discussed on the dev list and locking-notes.txt e) Fix bugs? Well... happy locking. /Stein Roger _________________________________________________________________ MSN Messenger http://www.msn.no/messenger Den korteste veien mellom deg og dine venner
---------------------------------------------------------------------
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.