On Aug 12, 2011, at 11:01, Jan Ciesko (GMAIL) wrote:

> What I was wondering though: if I commit a delete and run any svn command on 
> the REV-1 version in the post-commit hook, is it guaranteed that in the 
> meantime no other commits were run, thus making REV-1 invalid?
> Or in other words: pre-commit, commit and post-commit are atomic?

Well let's think about each of those.

The commit will not be finalized until after the pre-commit hook has run 
successfully. So the directory should continue to exist in the head of the 
repository for the duration of the pre-commit hook. It might be possible 
(though unlikely) that another developer will happen to delete the directory 
while the hook is running. To minimize the possibility of that messing up the 
script, the first thing the script should do is get the HEAD revision of the 
repository into a variable, and use that variable for the duration of the 
script:


#!/bin/bash
REPOS=$1
TXN=$2
SVNLOOK=/usr/bin/svnlook
SED=/usr/bin/sed
HEAD_REV=$($SVNLOOK youngest $REPOS)
PATHS_IN_REPOS=$($SVNLOOK changed $REPOS -t $TXN | $SED -n -E 
's/^D...(.*)$/\1/p')
for PATH_IN_REPOS in $PATHS_IN_REPOS; do
        TREE=$($SVNLOOK tree $REPOS $PATH_IN_REPOS -r $HEAD_REV)
        ... (do something with $TREE)
done



The commit itself is atomic. That's one of the fundamental properties of 
Subversion and is well documented so we don't need to go into it further here.

http://svnbook.red-bean.com/en/1.5/svn.basic.in-action.html

"An svn commit operation publishes changes to any number of files and 
directories as a single atomic transaction."



That leaves the post-commit. By this time the commit is finalized in the 
repository. So you can look at that new revision all you want and it's not 
going to change. Yes other commits might happen subsequently but your 
post-commit hook is called with the number of the newly-added revision, so just 
subtract one from that to find the last revision in which the directory still 
existed.

#!/bin/bash
REPOS=$1
REV=$2
SVNLOOK=/usr/bin/svnlook
SED=/usr/bin/sed
PREV_REV=$(($REV-1))
PATHS_IN_REPOS=$($SVNLOOK changed $REPOS -r $REV | $SED -n -E 
's/^D...(.*)$/\1/p')
for PATH_IN_REPOS in $PATHS_IN_REPOS; do
        TREE=$($SVNLOOK tree $REPOS $PATH_IN_REPOS -r $PREV_REV)
        ... (do something with $TREE)
done



These examples do not properly handle paths that contain spaces. Also, 
PATHS_IN_REPOS could contain files and/or directories; if you want only 
directories, you'll have to skip the files somehow.




Reply via email to