4

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!

IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756
  • What you're describing is what a feature branch is, and I don't see why it would be pure evil. – JB Nizet Feb 27 '12 at 17:35
  • My understanding is that a feature branch would be something like `project/branches/new_feature/`, whereas I'm talking about developer branches like `project/branches/johnsmith/`. When John Smith is done coding something, his branch gets merged with `trunk/`. As opposed to the whole team committing to `/new_feature/`, and if John is behind, delaying the merge and subsequent release. This way the band marches on regardless of where John is. – IAmYourFaja Feb 27 '12 at 17:39
  • And http://martinfowler.com/bliki/FeatureBranch.html – IAmYourFaja Feb 27 '12 at 17:39
  • 2
    The developer is not developing nothing. He's developing a new feature of the application. If he's the only one to develop this feature, whether you call the branch johnsmith or feature32 doesn't matter. If there is a good chance that some other developer might help him or replace him, naming it feature32 makes more sense. If he's developing several features at once in a single branch, he will only be able to reintegrate the branch into the trunk when he has finished with all the features, which will make it more difficult for the other developers to integrate his changes in their own branch. – JB Nizet Feb 27 '12 at 17:42

3 Answers3

2

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.

Community
  • 1
  • 1
Stuart Lange
  • 4,049
  • 6
  • 24
  • 30
2

CollabNet, Inc., the original sponsor of Subversion, put together a list of Subversion Best Practices.

The final section of the list is “Know when to create branches”.

Branches depend on the culture of your software project. CollabNet describes three common branch systems in use.

  • The Never-Branch System
  • The Always-Branch System
  • The Branch-When Needed System

The Never-Branch system is used by new projects with no runnable code. It can also be used by solo developers.

The Always-Branch system is often used by projects that favor heavy management and supervision.

Each developer creates / works on a private branch for every coding task. When coding is complete, someone or something reviews all private branch changes and merges them to /trunk.

This system does require more merging when one or more developers makes multiple parallel changes to a module.

The Branch-When-Needed system is the system used by the Subversion project itself. It’s a system that makes sense when a development group releases their product by versioning.

Users commit their day-to-day work on /trunk. Users do not commit until after unit testing. The /trunk undergoes regression testing on a periodic basis.

Every so often, the trunk is tagged to a particular release or version of the product. If a prior version of the product is found to have an error, a branch is made from the version tag to fix the problem. This fix is then merged into the /trunk.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • +1 for 'depends on the culture'. Totally agree. Also depends on release cycles, use of continuous integration, developer personalities and many other factors – the_mandrill Feb 27 '12 at 22:57
1

To understand when branching should be done, ask yourself why you branch in the first place.

There are three main reasons why you need to branch:

  1. You have multiple versions of your product out there, and an older version has a defect. In this case, you create a branch with the older version, and fix it on the branch. Otherwise, you have to include all of the new code that you've added since the release.

  2. You have a few dozen programmers working on a project at Release 1.0. When the project gets near the release point, you want to stop adding features and fix bugs. However, that leaves most of your programmers with nothing to do but twiddle their thumbs while the two or three programmers responsible for the release work on finalizing the release. There's simply not enough work for everyone. In this case, you branch Release 1.0 and do your release off of the branch. Meanwhile, the rest of your developers can continue working on Release 2.0.\

  3. You normally have all developers working on the release and making small changes. However, there's a major project that's going to refactor the framework of your product. If you have the developers working on that check their code in the trunk with the other developers, you won't be able to compile your build and test the changes. Instead, you branch this special project into its own code line. Thus, the backend restructuring is done on a side branch while the rest of the development team can continue working on the trunk.

In the last case, the team working off the main trunk needs to make sure their code doesn't fall behind what's going on in trunk. They have to keep merging the changes in trunk to their side-branch. Otherwise, the code differences between the side branch and trunk become too great to do an easy merge.


The question is why is Case #3 so much more difficult than the other two cases. The answer is whether the branches are diverging away from each other or converging towards each other. In Case #1 and Case #2, the branches diverge. In Case #2, the Release 1.0 code will be different from the Release 2.0 code, and the Release 1.0 code will be even more different than the Release 3.0 code. In fact, sometime in the future, the code on the Release 1.0 branch will be irrelevant.

Meanwhile, in Case #3, the branches much converge towards each other. That means you have to keep them in sync. That requires effort and oversight. It takes a lot of energy to make sure the branches, which will eventually have to merge wholesale, must remain in sync.

This is why most sites now do branching when necessary and not use the older system of feature or development branches. Doing so adds a lot of complexity. Each branch has to be managed, and each merge must be carefully reviewed.


By the way, it's one of the reasons that distributed version control systems aren't always better than centralized ones. I've seen too many places that have used Git, then had the developers all work on their own little repository and never talking to each other. A week before the release, we'd get clobbered with a dozen patches and then have a race to merge all of the code into a deliverable version.

A centralize repository forces everyone to work on the same set of files. Add in a continuous build process, and you can make sure there are no surprises come the release. If everyone has to work off a centralized repository anyway, a distributed version control system doesn't really add all that much to the mix, and can cause problems if you allow developers to live in their own little caves.

David W.
  • 105,218
  • 39
  • 216
  • 337