Shelving vs. Branching/Merging vs. Labeling: Which should I use?

Of course I'll go with the default answer to all computing questions: "It depends."

I've seen this question, or a variation of it, come up several times lately. The most recent variation I saw was a forum post, to which Buck provided a pretty complete answer on the Branching vs. Labeling question.

Obviously we believe each of these features is potentially useful (or we wouldn't be shipping them); I'll go one step farther and say that many organizations will use all three - only a few are likely to find themselves using one exclusively. They complement each other in some areas, and serve disparate purposes in others.

Labels, generally, are a good way to keep track of "points in time", but not points in time at which things diverge - that's where branches come in. So, as Buck said, if you want to be able to reproduce a build, use a label. But if you're going to need to patch or hotfix that build, you should probably branch instead. But if you just need to see when a particular feature (requiring multiple checkins) was considered "implemented", a Label makes more sense.

Similarly, if you need to save off some changes for awhile, shelving is a quick and easy way to do so. If you'll make regular tweaks to those saved-off changes, though, then branching might make more sense.

Our team mostly uses branches and shelvesets, though we use labels as well. We have a branch that the daily development work proceeds within, and a 'higher' branch that formal builds come out of. We forked a branch for the Beta2 release, and a CTP will often get a branch as well. We use shelvesets to save off changesets that aren't quite ready yet (client changes that need server changes, major work is done but needs a little more error handling or a couple more unit tests), changesets that are ready but can't be checked in yet (depending on the timeframe: needs a code review, buddy build, QA signoff, or other additional 'approval' to be checked in), and just work in progress. We use labels for things like one-off or rolling builds, and I know some folks like to label the tree just before a major merge, so you can get back to the "just before these massive and/or breaking changes showed up" state without having to dig up which changeset committed the merge.

One dev likes to give me a shelveset with changes to the diff code before checking in the changes (QA isn't required to verify changes on a regular basis, only in the various 'release modes' approaching major milestones). I'll unshelve his changes, run them through a very grueling set of test data (it takes 9-24 hours to run, depending on the options chosen), and let him know if any failures were found. Then I'll run the (sometimes updated) shelved changes through another app that collects some performance data - to prevent perf regressions, or to measure improvement if the changes are perf work.

He could email me the changed files, but it's faster, easier, and more reliable to use shelving - if everything looks good, then he knows that shelveset is ready to go, where the mailed files didn't really capture the "potential checkin" that I just validated the way a shelveset does - he has to be careful to include the same versions of the same sets of files in the checkin, something the shelveset makes painless. Plus, it's hard to email across a rename, delete, or undelete. People have invented ways to do so - a script that accompanies altered/added file contents, for example - but shelving is intended to eliminate the need to develop or maintain such scripting tools.

In general, branching/merging could be used in any of these scenarios, but it's somewhat cumbersome for some of the edge cases where we're using shelve or labels instead. Or, to use the buzzword, shelvesets and labels are "lightweight".

As always, I'm interested to hear how folks use their source control tool(s), and where they find limitations in what their tools can do compared to what they want to do. And if I can find a team or three that gets to give up the "nightly checkins and struggle to produce a working build" approach by using shelvesets, I'll be a pretty happy camper.