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.