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.