The typical layout of a subversion repository is to have three directories (sometimes called resources) under the root: trunk, branches, and tags. These directories serve to hold the mainline development, experimental or incomplete development, and release code, respectively. While most everybody who has used subversion is familiar with trunk, some are not clear on the purpose of the other two.
To fully explain branches and tags, I'd like to start first with trunk. When it comes to source control, I operate under a simple philosophy: Trunk is always stable.
This means that under source control, the trunk resource should always be in a working state. A user or developer should be able to check out the contents of trunk and work with it right away. However, stable in this context does not mean that APIs or functionality can't change from revision to revision; it simply means that the code base should work without breaking. This is an important distinction.
Of course, leaving trunk in this state while working on large change sets and experimental updates conflicts with another established philosophy: Commit early, commit often. So, where do these changes go? Branches, of course!
Branches are basically temporary copies of trunk where a developer can work and commit and break as they like. Once the changes to a branch are stable, the branch can be reintegrated to trunk, and the branch deleted. This keeps trunk clean and stable, while allowing the developer to retain the benefits of revision control. A project can have as many unique branches as the developer or team likes. Branch names don't really have any rules, but most teams have some sort of preferred convention.
When a project is ready for a release, a special type of branch is usually created, called a tag. A tag can be a straight copy of trunk, serving as a marker in the project's revision timeline, or it can be a modified version of the code base derived from a build system. Tags are usually named for the release version they represent. Since tags represent a fixed release, they are not supposed to be modified once they are created. While subversion itself has no concept of tags (it treats them like any other branch), the established convention is that they are permanent and users do not expect them to change. Most third-party repository management tools will warn you if you are about to modify a tag.
A typical active subversion repository may look like this:
Let's say a developer - we'll call him Bob - is working on the project shown above. Bob is assigned Bug #209, and after reviewing it decides that the changes required to fix the bug warrant creating a branch. Bob creates his new branch from trunk, naming it bug_209, and switching his working copy to it. As Bob is working on his ticket, other developers are busy committing to their branches, and some are even committing to trunk. After a while, Bob decides he needs to check his code against the current trunk. To do so, Bob would merge the changes from trunk to his working copy, and if everything looks good, commit those changes back in to his branch. Bob has rebased his branch from trunk.
A little while later, Bob decides that his work is done, and the bug is fixed as confirmed by his regression tests. Bob switches his working copy to trunk, and merges the changes from his branch to his working copy. One last successful run of the test suite later, Bob commits his working copy into trunk, deletes his branch, and marks Bug #209 as ready to deploy. Bob has just reintegrated his branch into trunk.
Bob also happens to be the release master for his team, which makes him responsible for creating tags. Since Bug #209 was prioritized critical, he needs to push the fix into production as soon as possible. Bob uses the team's build system to make sure trunk is stable and ready to deploy, and then creates a release tag from the build output, which he names 1.2.1. Bob then uses the team's deployment tools to verify the tag and push the code out into production. Hooray!
In Bob's case, the fact that his team uses branches and tags efficiently allowed him to easily deploy the application into a production environment. Hopefully, you have a little better understanding as to what branches are, and how a good branching strategy comes into play during the testing and deployment phase of development.
I'm still working on a post that will describe a bit more of the magic that happens when Bob runs his build and deployment tools. :-)