The goals of any effective branching strategy should be
- Always know where your changes are
- Always know where your changes started from
The first is something you probably expected. The second you might not have but really should.
Without managing the starting point of your changes, you can run into
all kinds of issues when you're trying to combine changes across
branches via merges or rebases:
- Features released before they should be
- Expected fixes being lost
- Code conflicts because of duplicated efforts
Untangling each encountered issue takes away time from time that could have been spent on actual development.
So what should you be doing with your branches?
Start with a Main Trunk
Always have a main trunk that's used as the starting point for new branches for development efforts.
For the Insoshi development community, the main trunk is the master branch of the official Insoshi repository. However, while you can send pull requests, you can't directly push your updates and organize your changes on it. Instead, you should start a new branch off the official master branch that is the main trunk for your work. All updates should be merged onto it.
Some discipline is required to remember to merge back onto the trunk but it keeps you out a lot trouble. Mainly it helps you avoid regression where bugs that had been squashed appear to come back from the dead or features that were implemented a couple versions back disappear.
By having this clear starting point, you’ll also be able to update your integration and development branches with the latest version of the code via rebases. This is particularly useful if you have a long-running project whose development cycle will span more than a few releases.
Branch across Features
Starting new branches that track feature or fix development is the most natural thing to do. Features tend to be assigned to individual developers who would have a local development branch tracking a designated integration branch for a project. Or a developer working on multiple features might choose to create branches for each and merge them into a locally.
For more complex feature sets which may have multiple parts that can be worked on semi-independently, you may want to explicitly create feature integration branches. Subteams would use this as their development starting points and pull updates and push changes to them. The separate feature sets will then get merged together as needed during the course of development and at its completion.
Branch across Releases
A particular release may include one or more features or fixes. If you have a tightly defined feature/fix sets and timelines, you can create branches for each release and work directly off those.
More likely, however, will be the case where you’ll need to integrate individual feature development. You’ll create a release integration branch and merge feature integration branches onto it. To make your life easier, the feature integration branches should be updated to have the same starting point as the release integration branch.
Although they could continue to exist separately, the project release branches should be merged back to a main trunk. A temptation is to leave it the branch unmerged and start the next release directly from it. In that event, you’ll end up with a cascading series of branches that can complicate the tracking of updates.
Branching across Development Teams
If you and some other developers tends to work in lockstep with one another, you might want to have a branch set up where you will all be able to place your updates. This is meant more as a team area instead of being dedicated to a particular feature or release. This may be especially useful if you don’t have a clear assignment of feature work or fixes and just pick them off a list as you’re able to work on them.