Our team is being asked to upgrade from CVS to SVN, and although its not quite the Mercurial or Git I was hoping for, its at least a step in the right direction.
I know that a big hangup for development teams – at least with SVN (or any other branch-centric SCM) – is the topic of branching and merging.
I’ve read articles preaching that “feature branches” (branches enveloping the development of a specific new feature) are pure evil. And, after reading them, I tend to agree. But then that begs the question of when to branch, and when to merge?
I have been toying around with the notion of having developers check out of trunk/ but each having their own (individual) developer branches and committing new code to those branches. Then, whenever a developer is done with their work, we just merge the code pertaining to that work (located inside their own, “private” branch) with trunk. That way they’re not holding anybody else up, and if they get behind they won’t stall the release.
Just wondering what SO’s thoughts were on developer-centric branching. If its a terrible idea, why? Whats a better approach? Thanks in advance!
I’m one of those types who thinks feature branches are evil. Check out this related question for some discussion on this topic (including an answer by myself) : Is using “feature branches” compatible with refactoring?
I don’t like feature branching because it flies in the face of the central purpose of continuous integration (the practice, not the tool), which is to have developers integrating their work together early and often in the development process, and have that integrated work validated by an automated build process. By adopting a branch-per-developer workflow, you have by design made that practice impossible, and you’re back to developers making independent, unvalidated changes that then need to be integrated together in a “big merge” near the end of the development process.
The DVCS acolytes will say that this is purely a problem of the toolset. Now, I agree that there are version control systems that handle branching and merging much better than subversion. Such systems are certainly appropriate for the decentralized open-source projects for which they were designed. However, even if merging were trivially easy (which it can never be, even with ideal tools), you still have the problem of delaying integration until late in the process. This can be desirable in an open source project where there are only a few trusted gatekeepers to the trunk and many (less trustworthy) collaborators. However, on a commercial team, you really should be able to trust everyone to commit to the trunk and hence there should not be a need for gatekeepers.
In conclusion, here are my answers to your bolded questions:
When to branch? When to merge? I favor branching for releases, to establish a snapshot and to make bug fixes easy (merges in this case are trivial, because you’re talking about cherry-picking a revision or two between the trunk and the release branch). I generally avoid feature branches, unless it is really necessary to make wide-ranging changes across the code base. Any time you feature branch, you pay the penalty of the “big merge” later on.
What’s a better approach? In my organization, all developers check in directly to trunk. We have continuous builds (off trunk) for every application, and we regularly (every week or two) cut a new release branch (and create a dedicated build for each release branch). Instead of creating feature branches, we try to create new implementations of our interfaces to implement new or significantly modified functionality. These new implementations can remain unused in production until they are ready, at which time we can switch our applications to use them. Using an IoC container makes this process very easy.