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:
- http://www.cmcrossroads.com/bradapp/acme/branching
- 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:
- /main/develop/fix103
- /main/release01/fix105
See what I mean? Fix105 is obviously a fix done on a release branch instead of a develop one.
Although I'm not a fan of git, one extremely good thing that git helps with - it's a branching/merging popularization. Talking with people in forums I'm sometimes horribly surprized how they are literally *afraid* of branching and merging, making a bunch of "theories" about why branching is bad. That's amazingly stupid! And that's just because they use SVN which makes branching and merging a big pain in the buttocks.
ReplyDeleteSo some bad tools can completely break people's mind forcing them to avoid some good practices even when they switch to some good tool after a while.
Yes, I totally share your view. Git is doing an excellent job explaining branching and merging to everybody. In fact I think what's really popular about Git is more its ability to do branching/merging better than SVN than its distributed capabilities.
ReplyDeleteWell, I believe git first became popular because Linus himself made it and he presented it in Google ;) And *after* that people started realizing general advances of the things that he was advertizing :)
ReplyDeleteA few people (well, a few thousand people...) knew about DVCS before his speech.
Now it's had for people to switch to something else - because git is the only true SCM for them :)
Have you had any cases when people started using Plastic after git?
True! In fact his Google speech was slashdotted linking to this blog actually! :-)
ReplyDeleteWe've tons of cases of people moving away from CVS, SVN, Perforce, Clearcase, VSS... We had a few cases of teams thinking whether to move to Git or Plastic, but that's unusual. It seems teams considering OSS tools won't consider commercial products (unless they hit some big issue) and viceversa.
Moving away from Git into Plastic? I'd have to check but I don't think it's common. Consider the following: Git is brand new so if you just moved into it, you're not going to move away for two reasons (apply the same to SVN, CVS and even VSS!):
- First you've just landed there so you won't consider a new move anytime soon
- Second, even if you feel like changing is hard for people to admit a mistake so they'll stick with their current SCM for a while (normally until the one who made the decission leaves!). Of course this better applied to really *limited* tools like VSS/CVS and even SVN (I've seen teams sticking to VSS for years, huge teams, and suffering on a daily basis until the guy in charge of the original decission left!). Git has nothing to do with CVS/VSS/SVN, it's much better, so unless you miss something too big you won't leave it soon.
As a SCM developer I've the feeling Git is still on a different market than us (we don't have to compete against it ver often) but I really think it's a great system (Linus is a genius!!) and it obviously makes us work hard to put ourselves ahead of the game (which is not easy considering Git has probably more people working on it than we've! but so far I think we're doing a very good job) and come up with clear differences.
What we obviously see is a much bigger interest on DVCS, which is very good for Plastic!
I totally agree about the changes... It's amazingly hard for someone to go even a step aside :)
ReplyDeleteAs for competing with git... There's one more factor here such as the price ;) A huge part of OSS success is about being free of charge - and that's something that is really had to beat.
Here is Russia OSS is twice popular because for many companies (and therefore individuals) proprietary software costs too much to buy. Expecially when it's about some ClearCase-like things. I've been working with ClearCase for 3 years and it was provided by our contractior company.
That's why you guys are doing a great job - making a SCM that is good enough to be actually sold. :)
Thanks for this post. I am setting up procedures for our team to use Plastic, and have relied heavily on this and the original diagram.
ReplyDeleteHaving actually tried it now, there is one thing I would change. Instead of creating the release branch as /main/develop/release1.0, create it as /main/release1.0 and then merge to it from /main/develop. This is an extra step, but avoids some non-intuitive behavior when any folder contents have changed on /main/develop.
For more details about this, see the post titled "Integrating Grandchild Branch Loses Child Items" on the plasticscm forum.
Great post. I switched from Subversion to Git, and now to Plastic. I'm still fairly new to source control, so forgive me please, but with Plastic, do I need to worry about any merging? Especially as a sole developer using it at this time? For example, if I have 4 branches off the /main, do I need to merge the branches onto the /main line? Thanks!
ReplyDelete@delacombo: merging these 4 branches back or not will just depend on your development goals. I mean, are they separate developments, independent, which will be released separately? If so, maybe they don't need to be merged back.
ReplyDeleteBut, anyway, don't be afraid of merging... is much easier than you might think if you have the right tools, and you've them with Plastic.
Git does a fabulous job of branching & merging. I have worked with other source control systems like TFS & SVN.
ReplyDeleteI have adopted a similar strategy using Git for about a year now and no major issues so far. They only thing is that you have to merge often.
Hi Pablo! The correct URL for the "Streamed Lines" branching patterns paper is http://www.bradapp.net/acme/branching
ReplyDeleteIt is actually a much more thorough coverage of branching than the SCM Patterns book because "Streamed Lines" focuses exclusively on branching patterns & pitfalls (almost 60 of them) whereas the SCM patterns book is more of an introduction, taking only the most commonly recurring branching patterns and putting them together with other version-control and build-mgmt related patterns.