Git makes working with branches extremely easy. Especially compared to many of the version control systems that came before it. This has resulted in a standard workflow involving feature branches.
The idea is to branch from master when you begin developing a new feature. You do all of your development on that branch. When the work on the feature is complete, you merge your branch back to master. This works extremely well if the feature branch does not live for very long. If other people make changes to master before you can merge, a bit of coordination is needed.
Why Feature Branches?
In the past, when people didn’t use a VCS to track changes or when using a VCS without good branching support, you might reasonably make a change and find an error. But, you might not be able to tell if the error came from your changes or someone else’s. If you have a new failure, you couldn’t assume that the only change was the one you just made. It could be any change anyone had made.
Back in the bad old days, we had branches that would live for months. The effort of resolving conflicts between one of those branches and master was so great that we would create separate integration branches that would combine a branch with master to do all of the fixing needed to get the combined changes working. The hope was that we could get the integration branch stable before master changed so much that we would have to do it all over again.
Isolating Changes
A major benefit of feature branch is that it contains only one logical change. The idea is to complete the feature without being impacted by other people’s changes. Then, you can combine the changes that others have made at a point in time of your choosing. This makes troubleshooting any conflicts easier, because you know that your changes worked together, so any problems have to be in the way your code interacts with any changes on master.
Combining Changes
A feature branch allows you to isolate changes while you are working on them, but it does not remove the need to combine your changes with any changes that already happened on master. When combining those changes, you can either combine the changes from master into your feature branch or merge your changes directly into master.
The decision of which way to go has to do with the concept of conflicts. Any change on one branch has the possibility of conflicting with the changes on the other branch. Then either the VCS or the developer will need to resolve these conflicts. In a modern VCS (like git), many kinds of conflicts are resolved automatically. Obviously, if two developers make different changes to the same piece of code, a developer will be needed to look at the changes and decide what needs to happen.
The really difficult part is logically conflicts, where changes on one branch modifies the assumptions that the other branch depends on. This is what normally results in test failures after the code is merged. For many developers, this becomes a reason to combine the changes from master back to your feature branch, so you can fix any inconsistencies before merging back to master.
A good test suite helps keep this kind of conflict to a minimum. Just as importantly, your test suite should reduce the amount of troubleshooting needed when you do find a logical conflict.
Feature Branch Problems
The main point where feature branches become a problem is when they live for too long. The longer a branch lives, the more potential conflicts you will need to resolve when merging back to master. Feature branches work best when you are making a relatively small change, quickly enough that few other changes will overlap your development.
The rate of change of your code base will determine how long a feature branch can safely live. But, in all cases you want to avoid the case where a large number of other changes overlap any particular feature branch’s lifetime.
Conclusion
The goal of a feature branch is to separate changes for a new feature from other changes on the main line of development to simplify the development process. This goal is accomplished by separating problems caused by the implementation of the feature from problems caused by mainline changes that invalidate the assumptions that feature is based on.
By dividing the problem in half, feature branches have proven to be an effective way to develop software more quickly