views:

481

answers:

4

We use svn:externals to specific revisions of a library, e.g. like

xyzlib -r12345 https://asdf.asdf.local/xyzlib/trunk/

When you make a modification in your working copy to such a checked out external, it is possible to commit even though the external links to a specific revision and not the HEAD.

When you run svn update after the commit, the changes will be gone in the working copy because subversion reverts everything back to the revision 12345. So you never really see the changes yourself but they still are in the HEAD, which is bad.

Is it possible to forbid commits only when the external does not point to the HEAD revision?

+1  A: 

Since you are using https, I assume you are using mod_dav_svn. You could set up an additional url to your library repository, and only grant read-only access to it. That way even developers that can normally commit to the library, will not be able to commit through the svn:external.

Mike Miller
hm I dont really like this because when I switch to the HEAD of the writeable url all files have to removed and checked out again
martinus
So you are switching the svn:external to a different revision? I have never tried switching one before, but I don't see why it should force a remove on the working copy.
Mike Miller
The problem I guess is that it will _not_ switch, it will still be r12345 after next update. And committed changes will go into HEAD (or will fail with conflict). That is not what committing dev was intending either way.
Eugene
+2  A: 

You could try something like this: use a pre-commit script to check if the commit is going to a tag. If so, then fail out and provide a message. Read some more about subversion hooks. You'll have to re-write the regex so that it fails out if its not HEAD rather than failing if is a tag.

$SVNLOOK changed -t “$TXN” “$REPOS” | egrep -v “^[AD][[:space:]]+(.*/)?tags/[^/]+/$” | egrep “^[^[:space:]]+[[:space:]]+tags/[^/]+/.+”
if [ $? -eq 0 ] ; then
echo >&2 “***************************************”
echo >&2 “* Modification of tags is not allowed *”
echo >&2 “***************************************”
exit 1
fi
nont
A: 

If your not committed to keeping the external defined as a revision of trunk, why not just make a new tag based on that revision. You can then have your svn:external point to the tag, and use one of the documented access control methods to limit commits to your tag directory (or put the tag in a different repo and make that repo read only).

zlovelady
+3  A: 

For these kinds of validations I would also recommend a pre-commit hook, but instead of writing a script which can easily turn out to be impossible to understand I recommend using a library like SVNKit - http://svnkit.com/ (if you know Java).

I've written a few pre-commit hooks myself using this library and it is quite easy to work with. You write a small runnable Java program which is called from the pre-commit hook by Subversion. Then it is easy to extract e.g. properties or parts of the URL to do the validation and reject the commit if it doesn't apply to your "rules".

Take a look at the SVNLookClient and SVNChangeEntry classes - they have methods for the most common cases (e.g. extracting info about a commit in progress.)

Erik Finnman