“It was only when we started checking files into CVS, then checking out and building the result that we realized the team had newer copies of the source than the ones on the file share. Acceptance Testing had been going on for a month against binaries manually copied onto the server from who knows where.”
While a whole book could be devoted to version control philosophies and how to use tools such as CVS or Subversion, but a few things make for good version control.
These kinds of things should be under version control:
Project documents. These should be structured in such a way that developers can easily come up to speed on a project by examining the /doc folder. The definitive location does not have to be in version control (and can be troublesome due to merging issues with binary documents), but a recent copy can be placed for developers to read.
Specific versions of libraries where there is such a dependency
The bare minimum required to do a build.
Database schemas.
What should not be under version control:
.class files
WAR and EAR files
generated java source code (eg. from xdoclet).
generated hibernate .xml files.
anything that is the result of the build process (resulting JARs from other build processes are fine)
Only check in the bare minimum required to do a build. Generated WAR files, EAR files and .class files should never be checked in because they can be easily regenerated from the source.
Reproducibility is key – anyone should be able to check out a snapshot of the source and do a build using a single command. If you don't have a reproducable build, you don't have a release.
For rapid development use an optimistic locking version control system where multiple users can be changing the same file and later merge their changes, rather than explicitly locking files for editing.
Avoid branching where possible. A really good reason is needed for the complexity of branching, so do not include branching as part of your core development process. Most developers will not understand it. This does not mean “don't branch”; production maintenance is impossible without it, but don't branch simply to display your source code control prowess.