The current buzzword for feature flags is 'branch by abstraction'.
The idea is that instead of making a version control branch to change feature A to feature B and then merging back into the mainline of development, you build an abstraction over the thing you want to change, build a new implementation of that abstraction, switch out the two and then (if you like) remove the abstraction, all within the main line of development.
So instead of history that looks like this:
* Merge branch 'feature-cookie-login' into master
|\
| * Polish up cookie feature
| |
. * Switch from tokens to cookies
. |
. * Clean up and refactor login code
|/
.
.
.
Your history looks like this:
* Stop abstracting the authentication type.
|
* Switch from auth tokens to session cookies
|
* Add a SessionCookie authentication type.
|
* Start abstracting the authentication tokens as a generic authentication type
|
.
.
.
But with any completely arbitrary commits interspersed between those commits, as none of them break other code. The first one creates an interface, the second one reimplements the interface, the third switches the used implementation and the optional fourth removes the abstraction and deletes the old implementation.
The idea is that instead of making a version control branch to change feature A to feature B and then merging back into the mainline of development, you build an abstraction over the thing you want to change, build a new implementation of that abstraction, switch out the two and then (if you like) remove the abstraction, all within the main line of development.
So instead of history that looks like this:
Your history looks like this: But with any completely arbitrary commits interspersed between those commits, as none of them break other code. The first one creates an interface, the second one reimplements the interface, the third switches the used implementation and the optional fourth removes the abstraction and deletes the old implementation.