Do you feel comfortable merging code?
This morning, I read two opinions on refactoring.
- Opinion 1 (Page not present)
- Opinion 2 (Page not present)
They recommend branching (and subsequently merging) code to:
- Keep the trunk clean.
- Allow a developer to walk away from risky changes.
In my experience (particularly with Borland’s StarTeam), merging is a non-trival operation. And for that reason, I branch only when I must (i.e. when I want to freeze a release candidate).
In theory, branching makes sense, but the mechanics of merging make it a very risky operation.
- Do you feel comfortable merging code?
- Do you branch code for reasons other than freezing a release
18 Solutions collect form web for “Do you feel comfortable merging code?”
Some loose guiding principles:
- Branch late and only when you need to
- Merge early and often
- Get the right person to do the merge, either the person who made the changes or the person who wrote the original version are best
Branching is just another tool, you need to learn how to use it effectively if you want the maximum benefit.
Your attitude to branching should probably differ between distributed open source projects (such as those on Git) and your company’s development projects (possibly running on SVN). For distributed projects you’ll want to encourage branching to maximize innovation and experimentation, for the latter variety you’ll want tighter control and to dictate checkin policies for each code line that dictate when branching should / should not occur, mostly to “protect” the code.
Here is a guide to branching:
Here is a shorter guide with some high level best practices:
Branching might be painful but it shouldn’t be.
That’s what git-like projects (mercurial, bazar) tells us about CVS and SVN. On git and mercurial, branching is easy. On SVN it’s easy but with big projects it can be a bit hardcore to manage (because of time spent on the branching/merging process that can be very long — compared to some others like git and mercurial — and difficult if there are non-obvious conflicts). That don’t help users that are not used to branch often to have confidence in branching. Lot of users unaware of the powerful uses of branching just keep it away to not add new problems to their projects, letting the fear of the unknown make them far from efficiency.
Branching should be an easy and powerful tool we’d have to use for any reason good enough to branch.
Some good reasons to branchs:
- working on a specific feature in parallel with other people (or while working on other features alternatively if you’re alone on the project);
- having several brand versions of the application;
- having parallel versions of the same application — like concurrent techniques developped in the same time by to part of the team to see what works the better;
- having resources of the application being changed on a artist/designers (for example in games) specific branch where the application is “stable” while other branches and trunk are used for features addition and debugging;
- [add here useful usages]
Branching is trivial. Merging is not. For that reason, we rarely branch anything.
Using SVN, I’ve found branching to be relatively painless. Especially if you periodically merge the trunk into your branch to keep it from getting too far out of sync.
We use svn. It only takes us about 5 minutes to branch code. It’s trivial compared to the amount of pain it saves us from messing up trunk.
Working in a code base of millions of lines of code with hundreds of developers branching is an everyday occurrence. The life of the branch varies depending on the amount of work being done.
For a small fix:
- designer makes a sidebranch off the main stream
- makes changes
- merges accumulated changes from main stream to sidebranch
- iterates through one or more of the previous steps
- merges back to main stream
For a multi-person team feature:
- team makes a feature sidebranch off the main stream
- individual team member operates on feature sidebranch as in “small fix” approach and merges to feature sidebranch.
- sidebranch prime periodically merges accumulated changes from main stream to feature sidebranch. Small incremental merges from the mainstream to feature sidebranch are much easier to deal with.
- when feature works, do final merge from main stream to feature sidebranch
- merge feature sidebranch to main stream
For a customer software release:
- make a release branch
- deliver fixes as needed to release branch
- fixes are propogated to/from the main stream as needed
Customer release streams can be very expensive to support. Requires testing resources – people and equipment. After a year or two, developer knowledge on specific streams starts to get stale as the main stream moves forward.
Can you imagine how much it must cost for Microsoft to support XP, Vista and Windows 7 concurrently? Think about the test beds, the administration, documentation, customer service, and finally the developer teams.
Golden rule: Never break the main stream since you can stall a large number of developers. $$$
I use Subversion and consider branching very simple and easy. So to answer question 1.. Yes.
The reason for branching can vary massively. I branch if I feel I should. Quite hard to put rules and reasons down for all possibilities.
However, as far as the “Allow a developer to walk away from risky changes.” comment. I totaly agree with that one. I create a branch whenever I want to really play around with the code and wish I was the only developer working on it.. When you branch, you can do that…
The branching problem is why I use a Distributed Version Control system (Git in my case, but there are also Mercurial and Bazaar) where creating a branch is trivial.
I use short lived branches all the time for development. This lets me mess around in my own repository, make mistakes and bad choices, and then
rebase the changes to the main branch so only clean changes are kept in history.
tags to mark frozen code, and it is easy in these systems to go back and branch off these for bug fixes without having a load of long lived branches in the code base.
I’ve been on a project using svn and TFS and branching by itself is a really simple thing.
We used branching for release candidate as well as for long lasting or experimental features and for isolating from other team’s interference.
The only painful moment in branching is merging, because an old or intensely developed branch may differ a lot from trunk and might require significant effort to merge back.
Having said the above, I would say that branching is a powerful and useful practice which should be taken into account while developing.
We use svn and have adopted a rule to branch breaking changes. Minor changes are done right in the trunk.
We also branch releases.
Branching and merging have worked well for us. Granted there are times we have to sit and think about how things fit together, but typically svn does a great job of merging everything.
I use svn, it takes less than a minute to branch code. I used to use Clearcase, it took less than a minute to branch code. I’ve also used other, lesser, SCMs and they either didn’t support branches or were too painful to use. Starteam sounds like the latter.
So, if you cannot migrate to a more useful one (actually, I’ve only heard bad things about Starteam) then you might have to try a different approach: manual branching. This involves checking out your code, copying it to a different directory and then adding it as a new directory. When you need to merge, you’d check out both directories and use WinMerge to perform the merge, checking in the results to the original directory. Awkward and potentially difficult if you continue to use the branch, but it works.
the trick with Branching is not to treat it as a completely new product. It is a branch – a relatively short-lived device used to make changes separately and safely to a main product trunk. Anyone who thinks merging is difficult is either refactoring the code files so much (ie they are renaming, copying, creating new, deleting old) that the branch becomes a completely different thing, or they are keeping the branch so long that the accumulated changes bear little resemblance to the original.
You can keep a branch for a long time, you just have to merge your changes back regularly. Do this and branching/merging becomes very easy.
I’ve only done it a couple times, so I’m not exactly comfortable with it.
I’ve done it to conduct design experiments that would span over some checkins, so branching is an easy way to wall off yourself a garden to play in. Also, it allowed me to tinker while other people worked on the main branch, so we didn’t lose much time.
I’ve also done it when making wide ranging changes that would render the trunk uncompilable. It became clear in my project that I’d have to remove compile-time type safety for a large portion of the codebase (go from generics to system.object). I knew this would take a while and would require changes all over the codebase which would interfere with other people’s work. It would also break the build until I was complete. So I branched and stripped out the generics, working until that branch compiled. I then merged it back into the trunk.
This turned out pretty well. Prevented a lot of toe-stepping, which was great. Hopefully nothing like this will ever come up again. Its kind of a rare thing that a design will change requiring this kind of wide ranging edits that don’t result in a lot of code being thrown out…
Branched have to be managed correctly to make merging painless. In my experience (with Perforce) regular integration to the branch from the main line meant that the integration back into the main line went very smoothly.
There were only rare occasions when the merging failed. The constant integration from the main line to the branch may well have involved merges, but they were only of small edits that the automatic tools could handle without human intervention. This meant that the user didn’t “see” these happening.
Thus any merges required in the final integration could often be handled automatically too.
Perforces 3-way merge tools were a great help when they were actually needed.
Do you feel comfortable branching code?
It really depends of the tool I’m using. With Starteam, branching is indeed non trivial (TBH, Starteam sucks at branching). With Git, branching is a regular activity and is very easy.
Do you branch code for reasons other than freezing a release candidate?
Well, this really depends of your version control pattern but the short answer is yes. Actually, I suggest to read the following articles:
- Version Control for Multiple Agile Teams by Henrik Kniberg
- FeatureBranch by Martin Fowler
I really like the pattern described in the first article and it can be applied with any (non Distributed) Version Control System, including Starteam.
I might consider the second approach (actually, a mix of the both strategies) with (and only with) a Distributed Version Control Systems (DVCS) like Git, Mercurial…
We use StarTeam and we only branch when we have a situation that requires it (i.e. hotfix to production during release cycle or some long reaching project that spans multiple release windows). We use View Labels to identify releases and that makes it a simple matter to create branches later as needed. All builds are based on these view labels and we don’t build non-labeled code.
Developers should be following a “code – test – commit” model and if they need a view for some testing purpose or “risky” development they create it and manage it. I manage the repository and create branches only when we need them. Those times are (but not limited to):
- Production hotfix
- Projects with long or overlapping development cycles
- Extensive rewriting or experimental development
The merge tool in StarTeam is not the greatest, but I have yet to run into an issue caused by it. Whoever is doing the merge just needs to be VERY certain they know what they’re doing.
Creating a “Read Only Reference” view in Star Team and setting it to a floating configuration will allow changes in the trunk to automatically show in the branch. Set items to branch on change. This is good for concurrent development efforts.
Creating a “Read Only Reference” view with a labeled configuration is what you’d use for hot fixes to existing production releases (assuming you’ve labeled them).
Branching is trivial, as most have answered, but merging, as you say, is not.
The real keys are decoupling and unit tests. Try to decouple before you branch, and keep an eye on the main to be sure that the decoupling and interface are maintained. That way when it comes time to merge, it’s like replacing a lego piece: remove the old piece, and the new piece fits perfectly in its place. The unit tests are there to ensure that nothing got broken.
If merging is too much of a pain, consider migrating to a better VCS. That will be a bigger pain, but only once.
Branching and merging should be fairly straightforward.
- I feel very comfortable branching/merging.
- Branching is done for different reasons, depending on your development process model/
There’s a few different branch models:
Here’s a one
Trunk . . . .. . .... . ... . ..Release1 . . ... . .... . ...Release2 . . .. . ... . .. . ...Release3 . .
Now here’s a curious thing. Suppose Release1 needed some bugfixing. Now you need to branch Release1 to develop 1.1. That is OK, because now you can branch R1, do your work, and then merge back to R1 to form R1.1. Notice how this keeps the diffs clear between releases?
Another branching model is to have all development done on the Trunk, and each release gets tagged, but no further development gets done on that particular release. Branches happen for development.
Trunk . . . .Release1 . . . . .Release2 . ....... . ...... . ...DevVer1 . . . . . ...DevVer2 . .... . .... ... .Release3 .
There may be one or two other major branch models, I can’t recall them off the top of my head.
The bottom line is, your VCS needs to support flexible branching and merging.
Per-file VCS systems present a major pain IMO(RCS, Clearcase, CVS).
SVN is said to be a hassle here as well, not sure why.
Mercurial does a great job here, as does(I think)git.