views:

55

answers:

3

feature branches is when each feature is developed in its own branch and only merged into the main line when it has been tested and is ready to ship. This allows the product owner to choose the features that go into a given shipment and to “park” feature that are part written if more important work comes in (e.g. a customer phones up the MD to complain).

refactoring is transforming the code to improve its design so as to reduce to cost of change. Without doing this continually you tent to get left with uglier code bases that is harder to write tests for.

In real life there are always customers that have been sold new features and due to politics all the customers have to see that progress is being made on “their” group of features. So it is very rarely that there is a time without a lot of half-finished features sitting on branches.

If any refactoring has been done, the merging in the “feature branches” become a lot harder if not impossible.

Do we just have to give up on being able to do any refactoring?

+2  A: 

I like this provoking thesis ('giving up refactoring'), because it enriches discussion :)

I agree that you have to be very careful with bigger refactoring when having lots of parallel codelines, because conflicts can increase integration work a lot and even cause introducing regression-bugs during merging.

Because of this with refactoring vs. feature-branches problem, there are lots of tradeoffs. Therefore I decide on a case by case basis:

  • On feature-branches I only do refactorings if they prepare my feature to be easier to implement. I always try to focus on the feature only. Branches should differ from trunk/mainline at least as possible.
  • Taking it reverse I sometimes even have refactoring branches, where I do bigger refactorings (reverting multiple steps is very easy and I don't distract my trunk colleagues). Of course I will tell my team, that I am doing this refactoring and try to plan to do it during a clean-up development cycle (call it sprint if you like).
  • If your mentioned politics are a big thing, then I would encapsulate the refactoring efforts internally and add it to estimation. In my view customers in middle-terms will see faster progress when having better code-quality. Most likely the won't understand refactoring (which makes sense, because this out of their scope...), so I hide this from them
  • What I would never do is to refactor on a release-branch, whose target is stability. Only bug-fixes are allowed there.

As summary I would plan my refactorings depending on codeline:

  • feature-branch: only smaller ones (if they "help" my feature)
  • refactoring-branch: for bigger ones, where the refactoring target isn't completely clear (I often call them "scribble refactorings")
  • trunk/mainline: OK, but I have to communicate with developers on feature-branches to not create an integration nightmare.
  • release-branch: never ever
manuel aldana
+2  A: 

Feature branches certainly make refactoring much harder. They also make things like continuous integration and deployment harder, because you are ballooning the number of parallel development streams that need to be built an tested. You are also obviating the central tenet of "continuous integration" -- that everyone is working on the same codebase and "continuously" integrating their changes with the rest of the team's changes. Typically, when feature branches are in use, the feature branch isn't continuously built or tested, so the first time the "feature branch" code gets run through the production build/test/deploy process is when it is "done" and merged into the trunk. This can introduce a whole host of problems at a late and critical stage of your development process.

I hold the controversial opinion that you should avoid feature branches at (nearly) all costs. The cost of merging is very high, and (perhaps more importantly) the opportunity cost of failing to "continuously integrate" into a shared code base is even higher.

In your scenario, are you sure you need a separate feature branch for each client's feature(s)? Could you instead develop those features in the trunk but leave them disabled until they are ready?. Generally, I think it is better to develop "features" this way -- check them in to trunk even if they aren't production-ready, but leave them out of the application until they are ready. This practice also encourages you to keep your components well-factored and shielded behind well-designed interfaces. The "feature branch" approach gives you the excuse to make sweeping changes across the code base to implement the new feature.

Stuart Lange
The XP panjandrums are adamant about having only one codeline. I'm not sure how feasible it is to realise that in practice (i think you might need a trunk plus a maintenance branch for each supported release, which means at least two codelines), but it's certain that they agree with you.
Tom Anderson
I'm definitely in favor of maintenance branches (I tend to call them "release branches"). And I also think that there are some scenarios where a feature branch can be justified. I'm mostly opposed to the "always create feature branches so the managers can decide which features go into a particular release" approach because it fragments the code base too much. Trust me, I'm no XP fanboy, but I do think the principles behind the desire for a single code line are sound.
Stuart Lange
I think it also depends on tooling, whether branches and reintegrating are high costs. subversion somewhat is annoying whereas git solves it very nicely (branch/merge is core concept, extremely quick). The key question for branching is: "Do I need isolation, how much will be the reintegration costs?". I think that both extremes ("never branch", "always branch for every minor change") are wrong. It really depends...
manuel aldana
I totally disagree with your "bold" statement. I guess you're restricted somehow by your toolset. Try Git, or Mercurial or Plastic SCM and you'll see how refactoring is not that hard anymore http://codicesoftware.blogspot.com/2010/08/rename-support-on-merge.html
pablo
You guys are definitely right that merging is somewhat easier in certain tools (git, mercurial, accurev) than it is in others (svn). However, even if merging was trivially easy (which it will never be), you are still keeping parallel code lines separate until the "big merge" takes place. There is cost associated with this -- your team is not sharing and integrating as quickly as they would if they were on a single code line. Feature branches fundamentally break the principle of "continuous integration", which has many demonstrated benefits.
Stuart Lange
+3  A: 

Refactoring and merging are the two combined topics Plastic SCM focuses on. In fact there are two important areas to focus: one is dealing (during merge) with files that have been moved or renamed on a branch. The good news here is that all the "new age" SCMs will let you do that correctly (Plastic, Git, Hg) while the old ones simply fail (SVN, Perforce and the even older ones).

The other part is dealing with refactored code inside the same file: you know, you move your code and other developer modifies it in parallel. It is a harder problem but we do focus on it too with the new merge/diff toolset. Find the xdiff info here and the xmerge (cross-merging) here. A good discussion about how to find moved code here (compared to "beyond compare").

While the "directory merging" or structure merging issue is a core one (whether the system does it or not), the second one is more a tooling problem (how good your three-way merge and diff tools are). You can have Git and Hg for free to solve the first problem (and even Plastic SCM is now free too).

pablo
Does the Plastic merge tools work on a parse tree rather than plain text? If so which languages are supported?
Ian Ringrose