Nested Branch Issue following upgrade from TFS 2008 to TFS 2010

One of my customers upgraded a Team Project from TFS 2008 to TFS 2010.

As you probably know, the concept of first-class branches was introduced for the first time in TFS 2010. Along with this, there is a new restriction against having nested branches in TFS 2010.

During the upgrade process, TFS attempts to determine heuristically whether to convert a branched folder in TFS 2008 into a branch or to leave it as a branched folder in TFS 2010. Since there is no limitation against nested branched folders in TFS 2008, there is the potential that the upgrade is unable to convert all branched folders into first-class branches (without violating the new nested-branch restrictions). Therefore, the upgrade process may leave some branched folders as branched folders and may convert some branched folders to branches.

The first step, following an upgrade from TFS 2008 to TFS 2010 should be to validate the resulting branch structure to ensure that it is correct. There may be scenarios where it is necessary or desirable to convert a branch back to a folder or to convert a folder to a branch in order to end up with a more ideal branching structure. Because of the benefit of first-class branches (enabling branch visualizations), I would not recommend simply converting all branches back to folders wholesale. Rather, I would prefer to see as many branched folders converted to first-class branches, as long as doing so does not violate the new TFS 2010 restriction against nested branches.

Take the following scenario in TFS 2008 (branched folders are bold)

Start with the Main Folder in TeamProjectA ( $/TeamProjectA/Main)

Branch Main to DevTeam1 in a new Development Folder ($/TeamProjectA/Main -> $/TeamProjectA/Development/DevTeam1)

Now branch Main to a folder underneath DevTeam1 ($/TeamProjectA/Main  -> $/TeamProject/Development/DevTeam1/DevTeam2)

No branch Main to a folder underneath DevTeam2 ($/TeamProjectA/Main -> $/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3)

TFS 2008 should not object to this three-level nesting of branched folders.

Next upgrade this Team Project from TFS 2008 to TFS 2010. The upgrade process will look at each of the branched folders (Main, DevTeam1, DevTeam2, DevTeam3) and attempt to upgrade some or all of them to first class branches.

If it tried to convert all the branched folders to branches, the result would violate the TFS 2010 restriction on nested branches. For example it would be acceptable to convert both Main and DevTeam1 to first class branches since they are not nested in TFS 2008). But if you then attempt to convert either DevTeam2 or DevTeam3 from branched folders to first-class branches you would create the nested branching problem under DevTeam1.

Likewise it would be acceptable to convert DevTeam3 to a first class branch as long as DevTeam1 and DevTeam2 are left as branched folders. It is acceptable to have a first-class branch nested under a branched folder in TFS 2010.

Let’s suggest that, after upgrading the Team Project from TFS 2008 to TFS 2010, you *may* have the following folder / branch structure (bold italics indicate first-class branch and bold non-italic is branched folder):

$/TeamProjectA/Main

$/TeamProjectA/Development/DevTeam1

$/TeamProjectA/Development/DevTeam1/DevTeam2

$/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3

Note, only DevTeam3 is a first-class branches in this scenario at this point.

Next, try to branch Main under DevTeam3 to create DevTeam4 ($/TeamProjectA/Main -> $/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3/DevTeam4). Note since DevTeam4 is nested under DevTeam3, it cannot become a first-class branch, and this operation will fail.

If you uncheck the option to convert folder to branch, this operation should work. If you do not uncheck this option then the operation will fail as you are trying to nest a first-class branch under an existing first-class branch. Note, you can only uncheck this option of the source of a branch operation is a branched folder. If the source is a branch, this option is not available.

Note, the same scenario would happen if DevTeam1 was a first class branch and DevTeam2 and DevTeam3 were branched folders in TFS 2010:

$/TeamProjectA/Main

$/TeamProjectA/Development/DevTeam1

$/TeamProjectA/Development/DevTeam1/DevTeam2

$/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3

Try to branch Main under DevTeam3 to create DevTeam4 ($/TeamProjectA/Main -> $/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3/DevTeam4). Note since DevTeam4 is nested under DevTeam1, it cannot become a first-class branch. If you uncheck the option to convert folder to branch, this operation should work. If you do not uncheck this option then the operation will fail as you are trying to nest a first-class branch under an existing first-class branch.

Next, let’s suggest that you have a third scenario:

$/TeamProjectA/Main

$/TeamProjectA/Development/DevTeam1

$/TeamProjectA/Development/DevTeam1/DevTeam2

$/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3

Note that only Main and DevTeam3 are first-class branches. Now try to branch DevTeam1 to a new folder that is not nested under DevTeam1 (for example $/TeamProjectA/Development/DevTeam1 -> $/TeamProjectA/Test/Test1)

This operation will also fail if you do not deselect the option to convert folders to branches? Why? Because DevTeam1, even though it starts as a branched folder, it contains a nested first-class branch and therefore cannot itself be converted to a first-class branch during the branch operation.

Finally a fourth scenario, start with Main and DevTeam3 as first-class branches and DevTeam1 and DevTeam2 as branched folders:

$/TeamProjectA/Main

$/TeamProjectA/Development/DevTeam1

$/TeamProjectA/Development/DevTeam1/DevTeam2

$/TeamProjectA/Development/DevTeam1/DevTeam2/DevTeam3

Delete the DevTeam3 branch (but do not destroy it). You may now think you have this:

$/TeamProjectA/Main

$/TeamProjectA/Development/DevTeam1

$/TeamProjectA/Development/DevTeam1/DevTeam2

But if you try to branch DevTeam2 to create Test1 - it would appear this should work  ($/TeamProjectA/Development/DevTeam1 -> $/TeamProjectA/Test/Test1)

But since DevTeam3 was a first-class branch that was nested under DevTeam1, TFS 2010 thinks is still there (deleted but not destroyed). Therefore you cannot convert DevTeam1 to a first-class branch without first destroying DevTeam3 or deselecting the convert to branch option.

I have tested this last scenario  in TFS 2010. When you create a branch or convert a folder to a branch, a row is added to the branch table. When you delete the branch, without also destroying it, the associated entry remains in the branch table in the TFS database. I have seen a blog suggesting that the only solution is to manually altering the branch table in the  to remove the row associated with the deleted branch (for DevTeam3). Rather than modify a TFS table manually, I would recommend a couple of options first:

  • Convert DevTeam3 from branch to folder before deleting it
  • Or, destroy DevTeam3 after deleting it.

Both of these options will remove the row from the branch table.