Branching and merging strategies
A few days ago I’ve found a very interesting post describing in detail a very strong branching and merging strategy: http://nvie.com/git-model.
While the original post is about Git, it exactly describes the technique we’ve being describing and enforcing since we released Plastic SCM 1.0 back in 2006.
As the post states, there’re huge benefits if you use branching and merging correctly, and of course you need to have the right tools to do that (and as the author says, CVS and SVN were discouraging the whole branching/merging strategy since they were totally unable to do so).
If you’re familiar with Plastic and you take a look at the Git’s post, you’ll find the diagrams are drawn differently. But just take a look at the following figure:
What we do with the Plastic branch diagram is render the branches from left to right instead of top-down, which is much better to use the available space on any modern screen, especially panoramic ones.
So, the hand-drawn graphic shown above becomes something like the following if you use Plastic SCM:
I’ve used the conditional formatter to render branches with the same colors in the Git diagram above.
As you know, besides of being able to provide best of breed branching and merging, Plastic is also all about visualizing the change flow: from the branch diagram above to rapidly inspecting changes visually, displaying version trees or simply replicating branches back and forth.
That being said I’d like to add some remarks/comments based on best practices.
Identifying the branch per task pattern
The pattern used for new features (the task or feature branches the original post talks about) is known as branch per task
The model pushes branching to the limit and then instead of using branches just for new releases or hot fixes, it enforces branching off for every new task.
You can learn more about branching patterns here:
- And reading the most complete book about branching ever published: http://www.scmpatterns.com
Best practice: when to create task branches
Simple rule: create a task branch for every new feature or bugfix you’ve to implement.
It basically means: forget about mainline development even when it’s hidden on a secondary branch (it’s clear you don’t checkin to the main branch anymore): don’t checkin directly to the develop branch nor the release branch, always use branches to isolate your changes.
It can sound like overkill for SVN/CVS users but you know any modern SCM will let you create branches in a second, so there’s no real overhead.Important note: if you look at it carefully you’ll see that I’m talking about using task branches as rich-man changelists. Systems like Perforce (and new versions of SVN) implement the concept of changelist as a set of logically related changests. That’s exactly what a task branch is but: in a changelist you can’t have more than one revision of the same file or directory while you CAN do that with a task branch.
Best practice: task branch naming convention – issue tracking
I’ve seen a lot of projects out there using issue tracking for bugs, but then relying on hard-to-track mechanisms for new functionalities.
Issue tracking rule of thumb: use your issue tracking for everything: every change on your code will have an associated issue, no matter whether it’s a bug, a new functionality, a performance issue, a refactor... always create an issue on your favorite issue tracking / project management system. It will easily create the traceability you’ve been always looking for.
SCM rule of thumb: create a branch for each issue you’ve to code and use a naming convention to associate the branch with the issue on the issue tracking system. This way the branch to fix bug 1074 will be bug1074, or the branch to implement new feature 1075 will be something like feature1075.
Best practice: task branch starting point
How do you create your task branches? It’s clear you’ll have to branch off from the development branch but, at any given point?
This is how one of the branches I’ve created for the sample above looks like when you check its properties within Plastic SCM:
The fix103 branch starts from branch develop at changeset 4. Is it correct? Well, it’s perfectly doable but I’d encourage the following best practice instead:
- Create frequent intermediate releases on the develop branch. They can be daily builds (or nightly builds if you prefer) that passes the entire test suite.
- Once you’ve a stable release (passing all tests, not just a on-commit quick subset but all of them, like you’d do for a external release) label it accordingly.
- Only create task branches starting from well-known intermediate stable releases (or stable builds if you prefer)
Look at the following figure: although I mentioned before that develop branch should only be used as integration, it’s possible that we still do some intermediate checkins there (especially if we don’t enforce the best practice or if we do some fixes while running the test suite). We shouldn’t use any of this intermediate checkins as starting points but stable builds.
The benefit is clear: if any test doesn’t work on your task branch is because you’ve broken it, since you always start from stable origins.
Side note: fast forward merges and Plastic SCM
Plastic SCM always creates a changeset on merge even when a fast forward could be applied, to preserve the right (and visual) merge history. The author claims it can’t be done by default with Git, but we found it to be a very strong best practice so it’s the behavior Plastic SCM always does.
Best practice: branch namespace
You’ve noticed that Plastic SCM branches on the diagram above look like /main/develop or /main/develop/fix103 and so on.
In Plastic you normally create branches with an operation called “create child branch” which means your branch is going to be the child of a parent one. This is not only useful to set the right origin but also to understand, at first sight, how the branches are meant to be used.
For instance, you can have the following kinds of fix branches:
See what I mean? Fix105 is obviously a fix done on a release branch instead of a develop one.