TFS -- Sustainability of Cascading Branches - version-control

Branching guidance usually describes an immortal "Main" branch, with features branched from Main, and merged back to Main, and Releases branched from Main, with further branches of a Release as necessary for Service Packs, RTMs, etc. The guidance regarding Main is often simplified to "no trash in Main."
I'm working with a group that releases regularly (as often as monthly) and serially. To them it seems unnecessary to ever return work to the Main branch. They use TFS 2010--diagramatically their branching structure looks like this:
Daily builds on a branch are made; eventually the branch goes to production. Any hotfixes to a branch are applied directly to that branch, and optionally merged forward to any future in-flight branches.
This group's branching strategy has been described perjoratively as the "Cascading Branches Antipattern." But is it really, given that these branches release to production, and then (usually) have a fairly short time to live?
Is this practice of cascading branches in TFS sustainable over the long term. If not, what are the limits, and when (after how many branches) might they be reached?
Is there any reason to NOT "destroy" Main, R1, R2 (etc.) eventually, or is there a "gotcha" that will prevent destroying and reclamation of space on the SQL server that is hosting the source code repository?

Cascading branches can work. I also can't think of any technical reason why destroying very old (preferrably archived) branches would impact the newer cascaded branches. Here are some issues to consider:
Developers have to map a new branch to their workspace after every release.
Developers have to manually move any work to a new branch if they weren't able to check it in before release (vs. just checking in to the same working Dev or Main branch after release.)
If you have one or more developers working in a child branch of Rn and a decision is made to move their work to Rn+1 then a baseless merge will be required to avoid checking into the original parent Rn branch.
MAKE SURE YOU SECURELY LOCK EACH BRANCH after release. All those branches will increase risk of a developer accidentally checking in a change to a released branch.
You need to adjust build definitions and any other path-specific artifacts after each cascade. If all development just works out of Dev (or Main) then the primary workspace and related build/project artifacts remain the same over time.
How do you work on a parallel features in isolation when you don't know which feature(s) will ship in Rn? (If you have a main branch the you can have multiple child feature dev branches from Main, then merge a feature branch only when it is stable and ready to merged to ship in the next release.)
I believe Jeff Levinson did a presentation that described branching evolution starting with single branch, then cascading branch, then Main+Release and a couple variations (while describing pros and cons of each). Check out Branching and Merging Practices - Jeff Levinson (Teched 2010 Video) (or related Branching & Merging PPT).
Enjoy! -Zephan

Related

Perforce and Feature Branching

At our company we use Perforce for our source control and version management. Currently we implement feature branching with the following "tree"
Hotfix01 - Hotfix branch
Hotfix02 - Hotfix branch
HotfixNN - Hotfix branch
Main (continuous trunk)
RC - Release Candidate branch (next release)
Working01 - Working branch, feature branch.
Working02 - Working branch, feature branch.
Working03 - Working branch, feature branch.
WorkingNN - Working branch, feature branch.
We setup the branches ahead of time. Not that this really matters. Branches off RC are feature branches. Right now we have >50 developers, Analysts and QA team members that are working individually or as a team on various projects, defect fixes, etc. When work comes in you find a free branch (we track that separately), claim that branch (e.g. Working56), do a force merge/sync from RC to that branch (to make sure it's exactly what's in RC at that moment), do your work (code, peer review, QA) while continuously merging any changes from RC to your working branch (at least once per day, perhaps more often as needed) and when you are done you copy the changes up to RC.
This works, but it means we have (at this time) 300 working branches to manage. We would like to implement feature branching in a more sane way where we would use branch mapping and such to create a branch as needed, named after what it's for and then once we merge it back to RC we want it to no longer show up in the depot forever (at least, not for every developer). Basically we want to see only those branches with active development as feature branches, hiding branches we are done with.
What is the best practice? Can this be done with perforce using either branches or streams? Are we missing something with Branch specifications that would allow this? Should we just not worry and allow thousands or tens of thousands of feature branches to pile up in the depot view under RC? Is the way we are doing it now the best we can hope for?
We've been using Perforce for 10 years and this is still a question that haunts us daily.
Task streams are designed for this.
https://www.perforce.com/perforce/doc.current/manuals/p4v/streams_task.html
Create the task stream, do your work in it, merge/copy back to the parent, then unload the task stream.
Common task stream gotchas:
Do not try to reuse or reparent them. One stream per task! If you try to reuse task streams their beneficial features mostly don't work but you still get all of the limitations.
The modified depot files live on after the task stream is unloaded. Adjust your mental model to use the list of streams as the source of truth for which streams are active, not the folders in the depot tree.
If you can handle those, task streams are hugely useful.

Trunk Based Development suggestion required

I was looking up good resources on branching strategies after doing feature branching for quite a few years and struggling with lots of branches and merge nightmares. Feature branches did give us a good isolation in managing releases in a pretty granular way as to which features should go to release. However, the problems they posed (many branches, merge conflicts) were way more than the benefits they gave.
We work with Oracle database (with 5000 objects) at back end. We also have multiple teams working on different areas of the same product. We are using Visual Studio with TFS (no DVCS).
The more branches we create, more database instances we require to give proper isolation in functional testing in those branches (each branch - one db instance) which are another set of problems.
We are adopting scrum and are searching for a branching model that will suit our release cycle (4 times a year) and CI builds. We are planning to do 5 regular sprint and 1 hardening sprint for each release.
From a feature branching model, we reworked our branching model to a very simple branching like below -
Development branch is working as our "Trunk" (for Trunk Based Development) and ALL developers (all teams) are committing to this branch (for quarterly release), testers are testing in this branch and CI server (Jenkins) is building this branch daily. We just need a clean MAIN at any time for safety as "Single Source of Truth for Last Release" which come to our use often for several reasons.
Maintenance branch is our bug fixing branch (hotfix) and is released several times during the year (irrespective of quarterly release). We prefer not to work directly on the main branch as want to have a "clean" Main branch. We do not want to let code go to Main without "manual" / functional testing done. Once a bug fix release is done, code is merged from Maintenance -> Main -> Development to integrate the bug fixes into Development.
We typically do not require the "Release Branches" as suggested in TBD since we will be continuously doing the bug fixes in the Maintenance branch, release from Maintenance and then merge the changes to Main (and then Development). We maintain only "Last release" and in case previous Release fix is required we create an old release branch from Labels in Main.
Have we modified the Trunk Based Development to an extent that it would pose problems in future? What are your suggestions?
Refer:
http://paulhammant.com/2013/12/04/what_is_your_branching_model
http://paulhammant.com/2013/04/05/what-is-trunk-based-development/#comment-2765204723
You should make a maintence branch from the tag that was released, only if you encounter a bug. Actually that's a release branch, and it should be named for the release. Say rel_1.1. By the time you've pushed out release 1.2 and it is clear you're not going to roll back, delete rel_1.1.

Are there any problems with branching a branch in TFS?

We branch our whole master branch in TFS, following a somewhat git-like paradigm rather than branching specific sub-folders.
I have one such branch, for a feature. However this feature ended up really being two features, one dependent on the other. It's not possible to merge back to master yet, but I would like to keep the features separate so I can merge part A while I still work on part B.
Say I am working in branch A; is it fine to branch A to branch B, and then continue working on B? I would then merge A back to master in the near future, and then merge B into master later on.
I don't know if TFS has intelligence that could make this a problem if I want to merge master -> B later on, or if TFS is totally 'dumb' with tracking branches and doesn't care about such things.
In TFS 2012 merging has improved considerably. Among the improvements are the auto-merge engine, which reduces the number of conflicts and the baseless merge promotion to the UI.
In your case, when there's no merge relationship between two branches, a baseless merge should be performed. Once a branch relationship is established, subsequent merges will be normal.
For more details see the ALM Rangers Version Control Guide.

When is the right time to branch and when is the wrong time?

Is there a specific rule I should be using for when to branch in source control? Branches seem to be expensive because they require that the team have extra knowledge about where the features they want to work on should go.
Our development team sometimes finds itself working on a long term feature and a shorter term feature at the same time. That means we end up with:
Trunk
-Branch A (Short Term)
-Branch B (Long Term)
After they complete we have to merge A in to the trunk, then merge the changes to the trunk back in to B to make sure those edits still function. It's messy.
I am wondering if we can cut down on branches by using Labels (Or tags, or pins or whatever your Source Control Software of choice calls it). Maybe it makes sense to branch for the longer term project, but we could just do the edits for the short term project right in the trunk after applying a label to the stable release. That way we can always retrieve the source code that was stable if we have to do an emergency bug fix, but we don't have to deal with the branch.
What rules do you use to decide when to branch?
One way to reduce branching is to implement new features (especially smaller ones) directly on trunk. This is how we do it:
small features, which will are guaranteed to be completed before the next release, are implemented on trunk
for larger features, we create a feature branch ("Branch B" in your example)
once we are ready to create a release, we create a release branch (from trunk), e.g. named "branches/2.x". This branch is then used for testing and finalizing the release.
once the release is built, we tag the corresponding revision from the release branch (e.g. tags/2.0.0).
normal development then continues on the trunk. the release branch is used for maintenance of the 2.x line of the product (e.g. bug fixes are merged from trunk, or implemented directly on that branch)
In a small team, the time to branch is when you can't commit directly into the trunk. With svn (as I guess with other version controls as well), it is possible to postpone the decision to branch till the time one realizes that one cannot commit into the trunk.
To minimize the need to branch, a new feature can be worked on in the trunk itself by restricting the new-feature code within compile-time or run-time flags. This approach also allows to later turn off feature if not needed, do A/B split testing experiments with the feature, etc.
Of course with this approach it always helps to have a continuous testing that gives an early alert whenever the build/test-suite breaks on the trunk.
For one thing, this depends on the tool you use. Branches are more 'expensive' in Subversion than in Mercurial or git, because merges are harder to do. For another, it depends on your project/organization: you should probably have at least one branch per maintained version.
It depends on the VCS you are using. If you are using a tool that has good support for merging, then you should branch whenever you feel like it. When in doubt, create a new branch. If the UNIX epoch time is even, then you should branch. If it's, odd, you should wait a second, and then branch. If you are using a tool that doesn't support merging well, then you should consider changing tools. In other words, stop using a tool that makes it necessary to ask this question.
It’s normally poor practice to develop against the mainline or trunk. The trunk should be used as the master code set and should reflect the code that currently represents production. If you are not in production yet, it should represent the gold copy and should always build and be subjected to automated regression tests. It should not be used to show development status or activity. Protect your trunk from change and resist the temptation to allow developers to check out and lock code on a trunk. The only updates in my view should be via the merge process, when you are ready to repatriate your code to the mainline.
When branching you should consider the purpose, complexity and duration of the development.
• Is it to support a team of developers working on a new feature or a substantial piece of development?
• Are you using traditional processes or the various agile flavors that are out there?
• It is to accommodate the development of a patch or fix for production?
• What development and in particular, test activity will you accommodate on the branch and will you retain the branch until the derived artifacts are built, tested and deemed releasable?
There are many models out there but few give sufficient consideration to the "build" process and the implications of regenerating your releasable artifacts.
Let’s assume you have the following lifecycle: DEV->SYSTEM-INTEGRATIONTEST->UAT->PRE-PROD->PRODUCTION. Assume you create a branch from mainline to accommodate the development and build processes. Your development\build\test cycle continues right through to UAT. The artifacts produced from this branch have been exposed to sufficient testing to deem them potentially suitable for release. You are able to state that the artifacts signed off by the users were also exposed to system and integration testing.
Some folks advocate merging the source code to the trunk at this point and recommend that you create a RELEASE branch upon a successful trunk rebuild. For me this is fine if the solution is stable and requires no further change prior to production, otherwise you risk propagating bugs elsewhere. In variably it will need to change.
If you do unearth issues in PRE_PROD, where are these “Fix” changes going to be made? Many suggest that you can make the code changes directly in the release branch. If you proceed, this modification will produce a new build and a new set of artifacts. You may elect to push these artifacts back through PRE_PROD and on to production, as the underlying code has been validated through previous testing and the modifications made to stabilize the release are deemed risk free? But you have a problem.
You cannot state that the executables\artefacts released to pre-prod and subsequently production, have been tested in your lower environments. Despite confidence being high, the output from the release branch build is different from that produced from the development builds. This may fail audit.
Branching for me is about managing your code and not the build output or solely the release. If you advocate branching for release and release stabilization (pre-prod fixing), you must take the above risk combined with the need for significant regression testing into consideration.
On the basis that the trunk should represent production code, you cannot push code to it unless it has been pushed to production first. I advocate creating a branch that supports the development, build and release as a single cycle. To avoid branch longevity and unnecessary divergence from the trunk (and potential big bang conflict issues) limit the development as much as you can and release and repatriate often with the trunk to keep other development efforts current.

Should I create a new branch for every new bug that gets reported?

We use a JIRA as our ticket system. New bugs/tickets are submitted to that system. Once a bug is fixed, we create a new build and test it on our dev server. If everything is good we push it to the live server. Now I usually work on the trunk without any branching to fix the bugs. This is of course a problem. Because there can be many bugs in our system, but only certain ones get fixed at a time. However if I fix all of them in the trunk instead of a branch, then we are forced to test them all even if we did not had enough time to test them all. How do you usually fix bugs and branch etc..? (I am not sure if I explained it very well).
Here is the strategy I use. I develop in the main trunk. When the software is released, I branch it (say v1.0). When bugs come in, fix in the branch trunk and then merge back to main trunk. Here is a good synopsis of strategies that are available: http://www.cmcrossroads.com/bradapp/acme/branching/branch-structs.html
I'm not sure if it's the normal strategy but we do all work on the trunk and then backport bugfixes into release branches. Our main trunk is always 'unstable' and when we feel we have a trunk in a releasable state we branch it into a release branch. From then on buyfixes are ported back into the release branch and new functionality only gets added to the trunk. It means you can run your release branch through testing and focus on testing the bugfixes.
One common mode of operations is that the deployed software lives in a separate branch which receives only bugfixes. Where you actually develop those fixes is mostly irrelevant; to avoid interference with the current development, it makes sense to develop the fix on top of the "live" branch, then test/commit/deploy to the live system and aftewards merge the fix back into the trunk.
We have the same problem (or almost), and I think every developer team has it. I can unfortunately not yet give you an answer by experience, but only a theoretical one.
In my opinion, as long as it's a bug fix, it should be deployed as soon as possible.
What I am about to implement is a feature branch strategy, and a release branch.
This means we have to differentiate features from bugs. and what is deployed is branched separately (or labeled, in our case)
Doing this, you can still work on the trunk for the bugs, and deploy them to your testing server, and once it's tested and approved branch it to the release branch and deploy it.
you can also merge-in the bug fixes into your feature branch, or try to merge the feature later when you plan to deploy it to the testing server.
Anyway, the most important I think is to branch the long work that prevent you from deploying smaller bug fixes.
If you branch too much, you will have a merging problem. If you don't branch enough, you will have a deployment flexibility issue.
It depends on your version control system. If you're using git, where branches are cheap and merges are easy, then I would definitely create a new branch for each fix. This allows you to keep bug fixes independent of each other, allowing greater flexibility with respect to what gets merged into the master/trunk, and when.
On the other hand, if you're using Subversion, branches are more expensive (in terms of creating and switching/updating) and merging is more difficult. Often the cost/benefit ratio of a new branch isn't high enough (especially for small bugs) to make it worthwhile.
I wouldn't recommend branching on every reported bug. As you said, you may not decide to fix every bug that's reported, which would mean that you'd have a lot of dead branches to prune at some point.
If your tools & language support it, branching on every bug you decide to fix (and feature you decide to implement) isn't a bad idea. It allows you to develop and test each bugfix/feature when you have the budget and schedule to do so, and merge them back into trunk when you are ready.
We split our branches into product versions / release, so that each release has its own branch. The release from the branch is tested, and so we only need to test the fixes applied to that branch.
Additionally each product version has a dev and a main branch. Developers are allowed to freely commit to the dev branch without fear of interfering with the Release (only other developers!)
Unless you're using a distributed SCM (Mercurial, Git, ...) where branching is basically free, branching on every bug sounds like an unreasonnable amount of work.
The usual strategy with central repository SCM is to note the revision that is supposed to fix the bug, and test against a build made with a later revision. You can then merge the concerned revision back into the release branch.
We are using mercurial, and branching to fix bugs and then merge changes back is quite doable in a distributed SCM