6

I'm working in an environment where we regularly start working on a feature and then are directed not to release it. We then create other features that we do want to release.

My typical workflow is write feature -> commit to default.

This workflow has worked well historically but in this environment breaks because we need to remove features from the branch.

My thinking for fixing this would be to have a dev branch, where we copy over specific commits related to a given feature.

We use both git and mercurial. Our issue tracker is ALM (which is incidentally the worst piece of software I've ever worked with).

Is there a "standard" way to handle this kind of development? Is there tooling that helps support this workflow? Do these VCS systems have some lesser-known means of supporting it?

4

Each branch has a role. Branching for a feature is a good one as it allows the feature branch to specifically identify that role.

Always merging back to default implies that default is the roles of mainline, accumulation, and packaging - and this is where you are having trouble.

You should instead consider making a branch for the role of 'accumulation for the release' and then merging your features into the appropriate accumulation branch.

There is nothing saying you can't have multiple simultaneous accumulation branches. One branch for 'next target release' which also has the name '2.0' (multiple names on a branch can make understanding the intent of each easier - though it may also make it trickier to do all the name updates) and then another branch for '3.0'.

If your feature isn't intended to be in 2.0, but is intended to be in 3.0, merge it into 3.0.

Once you are complete with the 2.0 / next release branch, merge that back into default and release it. Then you branch again for the next release branch from default and merge 3.0 into the next release branch and continue from there.

This has the advantage that you can cleanly build the 3.0 branch at any time to see if there are troubles on the horizon - before 2.0 is even released. It also separates the roles and build policies for each branch allowing them be understandable.

Further reading (a favorite of mine when it comes to branching and source control): Advanced SCM Branching Strategies. In particular, it explains what each role is and how they work together. While its focus is perforce, it can be cleanly applied to git and other distributed version control systems. Once you read it, give git flow a read and see how those concepts are applied in that model.

3

I think that your workflow of writing a feature (or a bug fix) and then committing it to the "default" (which appears to be a main or trunk branch) is the problem. Instead, consider using an alternative branching strategy.

I'm typically only focusing on one release at a time, so there's an "integration" branch off of the trunk and then there are development branches for bug fixes or features (and sometimes, they are grouped if it makes sense to group them and force the acceptance of one to drive the acceptance of other bug fixes or features). When a feature is accepted for release, we move it from a development branch into an integration branch, where it will be part of a nightly build and go through a test cycle. When we release, we move from the integration branch to the trunk.

There are other branching strategies as well. If you search for some combination of the phrase "branching strategy" and your version control system, you'll probably come up with several articles and blog posts that may be more relevant.

2

One (common) way of solving your problem is with the use of branches, as described by the other answers. However, there is another solution: feature toggles (aka. feature flags).

The basic idea is that your program maintains a list of flags (the feature flags) that can be switched on and off, and the code that implements the feature checks its corresponding feature flag before doing its work. So you'd have feature toggles like 'ENABLE_NEW_LOGIN_FORM', 'USE_NEW_TAX_ALGORITHM', 'SHOW_TEASER_FOR_NEW_USER'. There are many ways to implement this, and many libraries that do it for you, but that is the basic idea.

Advantages (compared to to using branches):

  • You can merge to main/master as soon as a feature is done; this avoids maintaining branches for a long time, which can mean a lot of work (i.e. merge conflicts) if for example there are refactorings in the main branch.
  • You have one list of all the features that are completed (the list of feature toggles), instead of many feature branches, whose features may or may not be completed.
  • You can postpone the decision whether to release a feature or not, and change your mind anytime (as stakeholders are wont to). In contrast, once a branch is merged removing the code is tricky.
  • You can toggle features after installation or even at runtime, if you want (though this may add some complexity).

Disadvantages

  • You need some extra code and infrastructure for maintaining the feature toggles.
  • You will need some ugly (?) if/else checks in the code of each feature that can be toggled (though some languages/frameworks have nice alternatives).
  • You must test with both features switched off and on, so more testing.
  • Sometimes, you will have to maintain two codepaths in parallel for the two toggle states, instead of being able to remove the old code.
  • You must eventually take out feature switches to avoid them cumulating, which means some extra work.

I have used feature toggles when maintaining branches became too painful because of merge conflicts, and found them a very good solution, for the reasons outlined above.

The implementation is usually not difficult; it helps to have a good feature toggle library that plays nicely with the language/framework/runtime you use, and has the features you need (think about things like storage of feature toggles, easy administration, support for switching at runtime...). We used Togglz (for Java), but there are many options.

Also see: Feature Toggles vs Feature Branches

  • 1
    "implementation is usually not difficult"... yeah, but testing usually is – gnat Jul 15 '15 at 23:53
  • @gnat: Yes, this means more testing, as I mentioned. Nothing is free in life :-). However, in my experience this is manageable, as long as you keep the number of feature flags under control. – sleske Jul 16 '15 at 7:40
  • 1
    See also martinfowler.com/articles/feature-toggles.html – Gishu Feb 6 '18 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.