We would like to implement a policy that will force developers to commit only changes that will compile.
Is there a way to do such thing using pre-commit hook? If not, I'll be happy to hear any recommendation or workaround that will maintain the source integrity.
Having the pre-commit hook kick off a build would be complicated, because the repository does not yet have a revision with the state you want to check at that point. The repository does have a pending transaction which you can inspect with
svnlook; this can be used to implement some rules but there is no easy
svnlook export command to do a full build.
The pre-commit would also have to wait for the build result before rejecting or completing the commit, which will slow things down tremendously. I imagine this will encourage developers to do "one big commit at the end of the day" instead of doing many smaller (=reviewable) commits as appropriate.
solution 1: don't reject, roll back
Do what the rest of the world does: set up a continuous integration server (like CruiseControl, Team Build, etc.) which does a build for each commit. If the build fails, ridiculously loud alarms are triggered an email is send out. Any developers who feel the build failure gets in their way can then easily revert the changes.
solution 2: feature branches and integration manager
The trunk (or some other branch) is considered "blessed". Developers have read access to it but they do not make changes to it directly. Instead, all changes are done on a feature branch where one can commit freely. When a change is ready, the developer makes sure it merges cleanly to the trunk by merging trunk changes and resolving conflicts. He then notifies the integration manager. The integration manager can then perform quality control (like checking that things still build) and does a
svn merge --reintegrate to push the changes to the trunk. A bit heavy weight, but some projects use this process.