Sometimes there were problems with merging, but in general I liked it.

But recently I see more and more followers of idea to not make branches as it makes more difficult to practice continuous integration, continuous delivery, etc. And it sounds especially funny from people with distributed VCS background who were talking so much about great merging implementations of Git, Mercurial, etc.

I am nut sure this is the right platform for this, but yes, I would branch. But maybe you should think about merging back certain featuresets back to master before they are 100% finished (to give previews :P)
–
ZeissSSep 13 '11 at 10:59

I've always seen all commits as a merge, even if just from local to remote. Merging from branches are the same, just bigger change sets, so I don't understand what the argument either way is. Has anyone done any actual profiling on the performance of any of these techniques, or is it all just pre-mature optimization?
–
tylermacSep 13 '11 at 13:53

I would argue that branches would make CI easier...
–
tdammersSep 13 '11 at 13:56

12 Answers
12

Unless you are all working out of the same working tree, you are using branches, whether you call them that or not. Every time a developer checks out into his working tree, he creates a separate local branch of development, and every time he checks in he does a merge. For most teams, the question isn't if you use branches, the questions are how many and for what purpose?

The only way to do truly "continuous" integration is for everyone to work out of the same working tree. That way, you immediately know if your changes adversely impact someone else's. Obviously, that's untenable. You need a certain degree of isolation in a branch in order to accomplish anything, even if that "branch" is just your local working directory. What's needed is a proper balance of integration and isolation.

In my experience, using more branches improves the degree of integration, because the integration is done with precisely the people it needs to be done, and everyone else can more easily isolate non-related problems as required.

For example, I spent the last day tracking down three recently introduced integration-related bugs in our build that were blocking my "real" work. Having done my due diligence in reporting these bugs to the people who need to fix them, am I now just supposed to wait until they are finished to continue my work? Of course not. I created a temporary local branch that reverts those changes so I can have a stable baseline to work against while still receiving the latest changes from upstream.

Without the ability to make a new branch for that purpose, I would be reduced to one of three options: either revert the changes in the central repo, manually maintain the patches that revert them in my working tree and try not to accidentally check them in, or back out to a version before those bugs were introduced. The first option is likely to break some other dependency. The second option is a lot of work, so most people choose the third option, which essentially prevents you from doing more integration work until the previously found bugs are fixed.

My example used a private local branch, but the same principle applies to shared branches. If I share my branch, then maybe 5 other people are able to continue on with their primary tasks instead of performing redundant integration work, thus in aggregate more useful integration work is performed. The issue with branching and continuous integration isn't how many branches you have, it's how frequently you merge them.

If you reverse the unwanted commits in your new branch, doesn't that reverse them in the master branch when you merge into it? I would personally branch from a point before the unwanted changes, and cherry-pick the changes I depend on into the new branch.
–
AnthonyDec 27 '14 at 17:06

most resources seem to agree that choosing productive strategy depends on the particular project specifics

side note. Based on above it looks like any changes to project branching strategy need to be tested, measured and compared to other options tested

popular opinion is that merging with Subversion takes a lot of efforts. All who compared SVN and Git note that merging is critically easier with Git

an important factor seem to be whether production releases originate from trunk or branches. Teams doing prod releases from trunk (which seem to be not quite a popular way) are essentially prohibited to use unstable trunk strategy. Teams doing prod releases from branches have more branching options to choose from.

popular strategies seem to be stable trunk, unstable trunk and development (integration) branch

references

...Deciding on the best branching strategy is a balancing act. You must trade off productivity gains against increased risk. One way to validate a chosen strategy is to consider a scenario of change. For example, if you decide to align branches with the system architecture (for example, a branch represents a system component) and you expect significant architectural changes, you might have to restructure your branches and associated processes and policies with each change. Choosing an inadequate branching strategy can cause process overheads and lengthy integration and release cycles that prove frustrating for the whole team...

...Frequent, incremental integration is one of the signposts of success, and its absence is often a characteristic of failure. Current project management methods tend to avoid strict waterfall models and embrace the spiral-like models of iterative/incremental development and evolutionary delivery. Incremental integration strategies, like Merge Early and Often and its variants, are a form of risk management that tries to flush out risk earlier in the lifecycle when there is more time to respond to it. The regularity of the rhythm between integrations is seen by [Booch], [McCarthy], and [McConnell] as a leading indicator of project health (like a "pulse" or a "heartbeat").

Not only does early and frequent integration flesh out risk sooner and in smaller "chunks," it also communicates changes between teammates...

...In most source control systems, you can create hundreds of branches with no performance issues whatsoever; it's the mental overhead of keeping track of all those branches that you really need to worry about... Branching is a complex beast. There are dozens of ways to branch, and nobody can really tell you if you're doing it right or wrong...

...There are many aspects of a system to be considered when branching your code... In the end, the goal is to provide a sandbox for the context in which code is being written. Understanding the available options, when each option is best suited to the situation at hand and the cost of these options will help you in deciding how and when to branch...

http://www.snuffybear.com/ucm_branch.htm
Note given other references listed here, author's claim that "This article describes three key branching models used in Software Engineering projects" does not look justified. Terminology used does not look widespread (EFIX, Model-1,2,3 etc).

It almost sounds like heresy when I actually type it onto my screen, but if you'll bear with me for a moment, not only will I show you why I think this is essential for an Agile process, but I'll show you how to make it work...

...If I had to base my reasoning on one solid argument, it would be the value of continuous integration. I blogged about the value of CI and best practices in the past. I am a pretty big advocate of CI...

...You really have to ask yourself a question here: "Is all the overhead you are incurring from doing your complicated branching and merging strategy resulting in a real value that does not exist over a more simple strategy?"...

...A strategy I have effectively used in the past and have developed over time. I'll sum it up briefly here.

Everyone works off of trunk.

Branch when you release code.

Branch off a release when you need to create a bug fix for already released code.

http://blog.perforce.com/blog/?cat=62
...The worst case scenario is that you introduce a "semantic merge" problem, where the result of an automated merge is incorrect, but compiles OK and sneaks past testing, possibly even surviving long enough to be a customer-visible bug. Eek!

Adding insult to injury, because they can escape detection longer, semantic merge problems are harder to fix later, since the change is no longer fresh in the mind of the developer who originated the change. (It's usually best to merge changes soon after there made, ideally by the developer who originated the change if that's practical)...

Create the release branch when you are "feature complete," and plan to fix last-minute issues on this code line. In this case, the release branch is really a "release-prep code line," as described in Software Configuration Management Patterns, since you expect that there is still work to be done.

Change your work style to avoid final integration work, working off of the active development line.

Branch for the new work by creating a task branch and merging that work into the active development line after the release is complete.
...A rationale for branching is to isolate code at the end of a release so that it can stabilize. Isolation through branching often masks a quality problem that will end up manifesting itself in the added cost of maintaining parallel streams before a product is released. Branching is easy. Rather, it's the merging and the cognitive overhead of understanding how changes flow between branches that are difficult, so it's important to choose a process that minimizes the cost of branching and merging...

We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the "integration branch". This is where any automatic nightly builds are built from....

http://svnbook.red-bean.com/en/1.5/svn.branchmerge.html
...project policies vary widely concerning exactly when it's appropriate to create a feature branch. Some projects never use feature branches at all: commits to /trunk are a free-for-all. The advantage to this system is that it's simple—nobody needs to learn about branching or merging. The disadvantage is that the trunk code is often unstable or unusable. Other projects use branches to an extreme: no change is ever committed to the trunk directly. Even the most trivial changes are created on a short-lived branch, carefully reviewed, and merged to the trunk. Then the branch is deleted. This system guarantees an exceptionally stable and usable trunk at all times, but at the cost of tremendous process overhead.

Most projects take a middle-of-the-road approach. They commonly insist that /trunk compile and pass regression tests at all times. A feature branch is required only when a change requires a large number of destabilizing commits. A good rule of thumb is to ask this question: if the developer worked for days in isolation and then committed the large change all at once (so that /trunk were never destabilized), would it be too large a change to review? If the answer to that question is "yes," the change should be developed on a feature branch. As the developer commits incremental changes to the branch, they can be easily reviewed by peers.

Finally, there's the issue of how to best keep a feature branch in "sync" with the trunk as work progresses. As we mentioned earlier, there's a great risk to working on a branch for weeks or months; trunk changes may continue to pour in, to the point where the two lines of development differ so greatly that it may become a nightmare trying to merge the branch back to the trunk.

This situation is best avoided by regularly merging trunk changes to the branch. Make up a policy: once a week, merge the last week's worth of trunk changes to the branch...

http://thedesignspace.net/MT2archives/000680.html
...This section of the Eclipse CVS tutorial is based on Paul Glezen's article on the Eclipse website: Branching with Eclipse and CVS, and is used with his permission under the terms of the EPL license. The changes I am making to his version are mainly to expand it with more step by step images and explanations, and integrate it with my own beginner tutorials in an attempt to make it more accessible to beginners and designers. Experienced developers will probably prefer to work from Paul's version...

Branch-by-release Model: One of the most common branching strategies is to align branches with product releases. A branch holds all the software development assets for a single release. Occasionally, updates need to be merged from one release to another, but they usually never merge. Branches will be discontinued when a release is retired.

Branch per Promotion: Another very common approach is to align branches with software asset promotion levels. A specific development version is branched off into a Test branch, at which all the integration and system testing is performed. When you complete testing, the software development assets are branched into the Production branch and ultimately deployed.

Branch per Task: To avoid overlapping tasks (or activities) and a loss in productivity, you can isolated them on a separate branch. Keep in mind that these are short-term branches that should be merged as soon as the task is completed, for otherwise the merging effort required may exceed the productivity benefits of creating them in the first place.

Branch per Component: You could align each branch with the system architecture. In this strategy, you branch off individual components (or subsystems). Then each team developing a component decides when to merge their code back into the development line that serves as the integration branch. This strategy can work well if system architecture is in place and the individual components have well-defined interfaces. The fact that you develop components on branches enables more fine-grained control over software development assets.

Branch per Technology: Another branching strategy aligned with the system architecture. In this case the branches are aligned to technology platforms. Common code is managed on a separate branch. Due to the unique nature of the software development assets managed on the branches, they probably never merge...

Do not branch unless your development team needs to work on the same set of files concurrently. If you are unsure about this, you can label a build and create a branch from that build at a later point. Merging branches can be time consuming and complex, especially if there are significant changes between them.

Structure your branch trees so that you only need to merge along the hierarchy (up and down the branch tree) rather than across the hierarchy. Branching across the hierarchy requires that you use a baseless merge, which requires more manual conflict resolution.

The branch hierarchy is based on the branch parent and branch child, which may be different than the physical structure of the source code on disk. When planning your merges, keep in mind the logical branch structure rather than the physical structure on disk.

Do not branch too deeply. Because it takes time to execute each merge and resolve conflicts, a deep branching structure can mean that changes in a child branch may take a very long time to propagate to the main branch. This can negatively impact project schedules and increase the time to fix bugs.

Branch at a high-level and include configuration and source files.

Evolve your branching structure over time.

Merging requires one or more developers to execute the merge and resolve conflicts. The merged source must be thoroughly tested because it is not uncommon to make bad merge decisions that can destabilize the build.

Merging across the branch hierarchy is especially difficult and requires you to manually handle many conflicts that could otherwise be handled automatically.
The decision whether to create a branch can be reduced to whether the cost of merging conflicts in real time is higher than the overhead cost of merging conflicts between branches...

You are randomly instructed that "you need to run update". You then do an update - which takes ages to complete. And then, finally, you see that there were no changes that needed to be downloaded.

You are randomly instructed that "you need to run cleanup".

You have huge merge problems. For example, you use ReSharper to rename a class, and some else has updated that class in the meantime. You then see the dreaded tree conflict error (shudder). Or even worse, you rename an entire namespace and folder (double shudder). Now you really are in for a world of pain.

Your merges tend to be more and more manual. You frequently have to use WinMerge because Subversion hasn't got a clue.

You are often waiting around for Tortoise to update/check for modifications/anything.

I have a subversion repository on my USB pen drive. I get tree conflicts and merge problems with that, and I'm the only user!

http://www.zeroturnaround.com/blog/continuous-integration-and-feature-branches/
more detailed analysis of branching interplay with continuous integration, based on concrete experience with Hudson/Jenkins - along with a couple of useful references
...My greatest discovery was that although CI is about committing, pushing and getting feedback often (i.e. the CI cluster provides you with feedback that your workstation could never give you in the same amount of time), the true purist CI actually has one more requirement — that the team needs to work on the same baseline...Materials used

http://codicesoftware.blogspot.com/2010/03/branching-strategies.html
...CVS and SVN were discouraging the whole branching/merging strategy since they were totally unable to do so...
...Simple rule: create a task branch for every new feature or bugfix you've to implement... 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...

http://en.wikipedia.org/wiki/Trunk_%28software%29
In the field of software development, trunk refers to the unnamed branch (version) of a file tree under revision control. The trunk is usually meant to be the base of a project on which development progresses. If developers are working exclusively on the trunk, it always contains the latest cutting-edge version of the project, but therefore may also be the most unstable version. Another approach is to split a branch off the trunk, implement changes in that branch and merge the changes back into the trunk when the branch has proven to be stable and working. Depending on development mode and commit policy the trunk may contain the most stable or the least stable or something-in-between version.

Often main developer work takes place in the trunk and stable versions are branched, and occasional bug-fixes are merged from branches to the trunk. When development of future versions is done in non-trunk branches, it is usually done for projects that do not change often, or where a change is expected to take a long time to develop until it will be ready for incorporating in the trunk...

...The trunk is where the ongoing development is supposed to happen. You really shouldn't have a problem with "broken" code, if everyone is testing their changes before committing them. A good rule of thumb is to do an update (get all the latest code from the repos) after you have coded your changes. Then build and do some unit testing. If everything builds and works, you should be good to check it in...

...Nope trunk isn't the best place. At our organization we always follow this approach: Trunk contains release code, so it always compiles. With new each release/milestone we open a new branch. Whenever a developer owns up an item, he/she creates a new branch to this release branch and merges it into a release branch only after testing it. Release branch is merged into trunk after system testing...

About 2 months ago, I had a short git session with Kamal and he shared with me the idea of story/branch. And as my team started to grow with more dev guys, I feel the need of encouraging more branching and now this has become a rule. For a project with automated tests defined with CI set up, a stable trunk is guaranteed and this practice can fit very well into it.

We don't use git but Subversion because that's how we started and we are still comfortable with it now (most of the time)...

...Eric's Preferred Branching Practice ...Keep a "basically unstable" trunk. Do your active development in the trunk, the stability of which increases as you approach release. After you ship, create a maintenance branch and always keep it very stable...

...In the next chapter I will delve into the topic of merging branches...

...The basically stable branching philosophy states that the trunk should contain project data that is always close to being ready for release...
...More lenient variations of this philosophy allow anything that passes developer unit-testing to be merged into the trunk. Such a relaxed approach requires a release candidate to be branched off and put through a full QA analysis before publication...

...The basically unstable philosophy states that the trunk should contain the latest code, regardless of its stability, and that release candidates should be branched off for QA.

...More lenient variations also allow branching for experimental code, refactoring, and other special-case code. Merging of a branch back into the trunk is done by the managers of the branch. ...

Note above resource did not appear in any of the searches I performed (CVS related guidelines aren't popular anymore?)

Best practices in SCM (perforce article) athttp://www.perforce.com/perforce/papers/bestpractices.html
...six general areas of SCM deployment, and some coarse-grained best practices within each of those areas. The following chapters explain each item...Workspaces, Codelines, Branching, Change Propagation, Builds, Process...

@JohnFisher: SO has several answers which I believe longer than this. And another great answer in programmers is one guy who covered randomness of different rngs.
–
userNov 7 '13 at 10:06

1

supplementary reading: Google's vs Facebook's Trunk Based Development "They [Google and Facebook] don’t have merge pain, because as a rule developers are not merging to/from branches. At least up to the central repo’s server they are not. On workstations, developers may be merging to/from local branches, and rebasing when the push something that’s “done” back to the central repo..."
–
gnatJan 14 '14 at 10:22

If you have several teams working on different features at the same time, there's no way you can omit branching. You should share (partly implemented) code with team members, preventing other teams from getting your not-finished features.

Branches are the easiest way to achieve that.

Though it's good to shorten the branches lifecycle and avoid working on the same module in two branches at the same time - you'll have no conflicts\merge problems then.

But recently I see more and more followers of idea to not make branches as it makes more difficult to practice continuous integration, continuous delivery, etc.

Well does it make more difficult to practice continuous integration, continuous delivery, etc for you concretely?

If not, I see no reason to change your way of working.

Of course, it is good practice to follow what's going on and how the current best practices evolve. But I don't think we need to abandon our processes / tools / whatnot just because X (and/or Y and/or Z) said they aren't fad anymore :-)

The issue is more to use fast-forward merges (which include a branch history within another one), provided you squash first all the "intermediate checkpoint commits" (which can be an issue in case of rollback or git bisect).
See "Understanding Git workflow", in order to distinguish private branches (not meant to be pushed) from public branches, which will be completed by ff merges (fast-forward merges) provided that you make the necessary cleanup within the branch you are merging.
See also "Why does git use fast-forward merging by default?".

What an interesting set of answers. In 20+ years I have never worked at a company that made more than a trivial use of branching (Generally just to branch releases).

Most places I've worked rely on fairly quick check-ins and rapid detection/resolution of collisions--Agile methodology teaches that you can resolve problems more quickly if you notice them while both parties are actively thinking about that piece of code.

On the other hand, I haven't used git much and perhaps it's the inclusion of the git tag that influenced these answers--I understand that branch/merge is a given with git because it's so easy.

I want to downvote this not because I am against branching but because you suggest that they should be used ALL THE TIME.
–
maple_shaft♦Sep 13 '11 at 13:31

Where did he say that, did he edit it or something?
–
b01Sep 13 '11 at 13:42

setup your own local CI to watch your branch for short lived branches (2-5 days) that could be quite an overhead. Been there done that
–
gnatSep 13 '11 at 13:57

1

I was responding to the question of using branches in general or basically never using branches. As with any rule or policy good judgement should come into play. I don't collaborate on a lot of my projects, but I still make liberal use of branches primarly for the 3rd bullet I mentioned. Also as for the first bullet, how many times have you gotten an urgent request to get some feature/fix live, but then you go in and you have about 3 half finished features in master.
–
Bill LeeperSep 13 '11 at 16:36

The main problem with branching is the difficulty with merging back into the main branch when development is complete. Merging can be a manual and error prone process therefore it should be avoided most of the time.

Some notable exceptions where I prefer branching is for massive refactoring, giant features that take longer than a sprint to develop, or disruptive features that would interupt the development of other features during the majority of that sprint.

Sounds like you need a better practice for developing new features. I personally like to build my projects to that it is easy to isolate features, usually in a separate file/class/or whatever. That way adding or removing code doesn't cause any major disruptions in delivery or problems when merging in new code, or pulling out old code. This works well when developing with multiple developers as well. But I can understand if you're working a project that may not have been started by you, or you have no real say-so as to how the project continues.
–
b01Sep 13 '11 at 13:50

@b01, Thats pretty much spot on. Nobody can come up with the perfect design when requirements go back and forth and change faster than an ADHD child on crack. Other times you end up trying to refactor legacy code to improve the design and this situation does come up from time to time. It isn't the worst problem a team can have, and is a far cry better than some places I worked where even suggesting refactoring in a meeting will get you beat to death with a baseball bat like a scene out of The Untouchables.
–
maple_shaft♦Sep 13 '11 at 14:14

Totally disagree. If you split by quality branches, and merge frequently (daily is good), then you avoid nearly all "manual and error-prone" merges.
–
Paul NathanSep 13 '11 at 15:58

@Paul, Trust me that doesn't work for all projects or technologies. Think of a common XML configuration file like in Struts where everybody is dipping their hands into it everyday. But no, your way works all the time and I totally deserved the downvote. Thanks.
–
maple_shaft♦Sep 13 '11 at 17:07

1

@maple_shaft meta-hint, if you consider the tags (git) and post something the typical user of those tags would consider a negative, expect flyby downvotes. Flybys are almost always unjustified reaction to being butt-hurt by some comment you take personally. Consider it good because it boosts your rep through he roof.
–
Bill KSep 13 '11 at 20:26

We do use branches, but not at the granular level of feature. We use branches for each sprint. Branching in essence is not a bad thing IMO, because it simulates the concept of SOC in the feature, or sprint layer. You easily can recognize and manage which branch belongs to which feature or sprint.

The process at my organization makes extensive use of branches and (a process that looks a bit like) continious integration.

At a high level view, developers don't worry too much about merging with mainline, they just commit to the branch. a (semi-) automated process checks what features are scheduled to go into mainline, merges those branches and builds the product. The process works because we actually integrate this process of merging from the issue tracker, so that the build tool knows what branches to merge.

If two teams work on their own branch, they won't see the changes of the other team, even if both integrate the master branch. That would mean their development branches will drift apart and if one of the teams would merge with master, the other team has to rebase a lot of changes.

So even if you have branches for features I would urge you to make 'backports' of all refactorings to the master branch and keep the branch only for new features.

Backport refactorings

I think sometimes it might be more easy to use feature switches to disable new, untested features that should not go into production yet. That way all other teams will see the changes and no big bang merge has to happen.