In my current project I have to decide which technique to use when branching. I have two options (we'll assume that we already have decided to develop in the trunk):
Version branches
Make a branch whenever a new version is put on the test machines and tag it like "release0.1". Bugs are fixed in this branch (and then merged to the trunk of course) and when this release finally goes live it's tagged "release0.1.1". This leads to having a branch for every major version and a tag for every minor version. If a bug has to be fixed in the live-version, it's fixed in it's appropriate branch and then merged down to the trunk.
Version promotion
Have only three branches "trunk" (for development), "test" and "live". When a version is put on the test machines, the trunk is merged (promoted) into the "test" branch, bugs are fixed in that branch and when the version is released, the "test" branch is merged into the "live" branch. If we find a bug in the "live" branch, it's fixed there and then merged down to the trunk.
What are the pros and cons of these two philosophies? What are your own experiences? Are there any other - possibly better - methods available?