I'd like to prevent developers working directly on the trunk.

I'm aiming to enforce all developers off the trunk and to work on there own branches until CI tests are cleared. They then have to merge from the trunk to their branch (to pick up latest changes), run and pass tests before they merge back to the trunk.

Is there any rules for this style of SVN usage?


You have to setup a commit hook which handles this situation. But I'm not sure if you really can separate a commit to trunk from a merge to the trunk (May be based on svn:mergeinfo change)...but i would recommend to describe the need for that to the developers instead forcing it...and by the way the commit script must be written and tested and that's an effort which i think is not really needed if you explain that to devs.

+1  A: 

It would be a lot simpler to have your developers work on the trunk, but not commit changes "until they are happy". Your developers can more easily update their code with the committed changes made by the other developers.

The setup you describe is more for developers that have to get express authorization from a manager or a user before they merge their changes. You also have to manually manage the branch changes from one developer to the other developers that need those changes for their change. (Branch to branch merging).

I deny access to the Cobol developers in my group access to SVN trunk. I did it by writing my own Eclipse plug-in that automatically creates branches and performs the merge back to trunk.

Gilbert Le Blanc
+2  A: 

You cannot do that. Either they can write to a directory or they can't.

However, you might be able to write a pre-commit hook that detects if they're trying to do this and abort if that's the case.

Daniel Egeberg
I think this would work (we use the pre-commit hook to ensure that blank checkin comments are disallowed), however, be prepared to warn your users about this because the error messages you get on trying to checkin aren't obvious. I don't think there's an ability to add a custom error message for when a pre-commit hook fails.
@the_mandrill: Anything you write to STDERR in the hooks should be visible to the end user.
Daniel Egeberg
+1  A: 

I'm not an SVN expert by any means, and Daniel's answer makes sense, so I might need an SVN/WebDAV expert to tell me why this wouldn't work:

This page documents the WebDAV methods used by various SVN commands. And it appears that you could "lock" commit, rm, copy, mv, and mkdir by denying a user permission to use the MKACTIVITY method. This would still allow diff, merge, checkout, ls, cat, etc.

So then all you would need to do is set up, in your Apache config, a <Limit> or a <LimitExcept> directive inside of a <Location> directive corresponding to the trunk directory. I haven't tested this out, but it would look something like:

<Location /repo/myproject/trunk>
    AuthType Digest
    AuthName "Repository Admins Only"
    AuthDigestProvider file
    AuthUserFile "E:/Sites/.htpasswd-admin"
    <Limit MKACTIVITY>
        Require valid-user

And you should be able to nest that inside of your repository's main <Location> directive. This is all assuming you're using HTTPS to access your repository.

Lèse majesté
svn's "merge" is a local operation that only modifies the user's working copy. It must be followed by a "commit" to be useful. So locking down "commit" would prevent merges too, unfortunately.
Ah, that makes sense.
Lèse majesté
+2  A: 

To allow only merges into the trunk, you could use a pre-commit hook that tries to distinguish merges from ordinary commits and rejects the latter. You can tell whether a commit is a merge by checking if it changes the "svn:mergeinfo" property on any path. This mailing list thread has two examples of hooks that check for mergeinfo. The examples are actually trying to enforce its absence on specific paths, but if you reverse the logic, you can make a hook that accepts only merges.

It would still be possible for a developer to deliberately slip in other changes along with the merge, and it's not reasonably possible to detect that. Such a pre-commit hook will work as a gentle reminder to the developers that they probably meant to check in to a branch and not the trunk, but it only works as long as they're not deliberately trying to sneak around the policy.

A more ironclad solution would be to limit write access to the trunk to a small number of users whom you trust to do the right thing. Those users will then have to do the final "merge back to the trunk" step in every case. If the developers have already merged from the trunk to their own branch, then this final merge back is trivial to do, so would not be a great burden on your trusted users. In fact, the final merge back can even be done by an automated process whenever developers flag their branch as "ready to merge". I've seen in-house implementations of such an automatic merge process, but I don't know of anything publicly available.

+3  A: 

Limit trunk commits to a bot. That bot can do the conflict-free merge and commit to trunk. I've done just that; it's called mergebot (MIT licensed). It's a daemon and a Trac plugin to provide a way to have a branch per-ticket. Docs are thin, there are issues in corner cases, but it mostly just works.


Restrict their access to /trunk with SVN permissions. Allow them to read, but dis-allow to write. Assign one "architect" role who can write to /trunk. Developers will have to report to the architect when a branch is ready, the architect will pass tests manually, and then will merge into /trunk.