This is a quick set of guidelines for making the best use of Subversion in your day-to-day software development work.
There are many ways to lay out your repository. Because branches and tags are ordinary directories, you'll need to account for them in your repository structure.
The Subversion project officially recommends the idea of a "project root", which represents an anchoring point for a project. A "project root" contains exactly three subdirectories: /trunk, /branches, and /tags. A repository may contain only one project root, or it may contain a number of them.
Book reference: Choosing a Repository Layout.
When you commit a change to the repository, make sure your change reflects a single purpose: the fixing of a specific bug, the addition of a new feature, or some particular task. Your commit will create a new revision number which can forever be used as a "name" for the change. You can mention this revision number in bug databases, or use it as an argument to svn merge should you want to undo the change or port it to another branch.
Book reference: "Subversion and Changesets" sidebar, within chapter 4.
Try to create as many two-way links between Subversion changesets and your issue-tracking database as possible:
When committing the result of a merge, be sure to write a descriptive log message that explains what was merged, something like:
Merged revisions 3490:4120 of /branches/foobranch to /trunk.
Book reference: Tracking merges manually, and Merging a whole branch to another.
Your working copy's directories and files can be at different "working" revisions: this is a deliberate feature which allows you to mix and match older versions of things with newer ones. But there are few facts you must be aware of:
Book reference: The limitation of mixed revisions.
A nice feature of Subversion is that by design, there is no limit to the size of files it can handle. Files are sent "streamily" in both directions between Subversion client and server, using a small, constant amount of memory on each side of the network.
Of course, there are a number of practical issues to consider. While there's no need to worry about files in the kilobyte-sized range (e.g. typical source-code files), committing larger files can take a tremendous amount of both time and space (e.g. files that are dozens or hundreds of megabytes large.)
To begin with, remember that your Subversion working copy stores pristine copies of all version-controlled files in the .svn/text-base/ area. This means that your working copy takes up at least twice as much disk space as the original dataset. Beyond that, the Subversion client follows a (currently unadjustable) algorithm for committing files:
So while there's no theoretical limit to the size of your files, you'll need to be aware that very large files may require quite a bit of patient waiting while your client chugs away. You can rest assured, however, that unlike CVS, your large files won't incapacitate the server or affect other users.
When a file or directory is copied or renamed, the Subversion repository tracks that history. Unfortunately in Subversion 1.0, the only client subcommand which actually takes advantage of this feature is svn log. A number of other commands (such as svn diff and svn cat) ought to be automatically following rename-history, but aren't doing so yet.
In all of these cases, a basic workaround is to use 'svn log -v' to discover the proper path within the older revision.
For example, suppose you copied /trunk to /branches/mybranch in revision 200, and then committed some changes to /branches/mybranch/foo.c in subsequent revisions. Now you'd like to compare revisions 80 and 250 of the file.
If you have a working copy of the branch and run svn diff -r80:250 foo.c, you'll see an error about /branches/mybranch/foo.c not existing in revision 80. To remedy, you would run svn log -v on your branch or file to discover that it was named /trunk/foo.c prior to revision 200, and then compare the two URLs directly:
$ svn diff http://.../trunk/foo.c@80 \ http://.../branches/mybranch/foo.c@200
This is a hotly debated question, and it really depends on the culture of your software project. Rather than prescribe a universal policy, we'll describe three common ones here.
(Often used by nascent projects that don't yet have runnable code.)
Pros: Very easy policy to follow. New developers have low barrier to entry. Nobody needs to learn how to branch or merge.
Cons: Chaotic development, code could be unstable at any time.
A side note: this sort of development is a bit less risky in Subversion than in CVS. Because Subversion commits are atomic, it's not possible for a checkout or update to receive a "partial" commit while somebody else is in the process of committing.
(Often used by projects that favor heavy management and supervision.)
Pros: /trunk is guaranteed to be extremely stable at all times.
Cons: Coders are artificially isolated from each other, possibly creating more merge conflicts than necessary. Requires users to do lots of extra merging.
(This is the system used by the Subversion project.)
Pros: /trunk is guaranteed to be stable at all times. The hassle of branching/merging is somewhat rare.
Cons: Adds a bit of burden to users' daily work: they must compile and test before every commit.