TFS Web Site projects, TFS and branches can mess up your workspace...

Yet another issue experienced when working on multiple branches in TFS: working with branched Visual Studio Web Site Projects (not to be confused with Visual Studio Web Application Projects) could indeed result in the creation of messy mappings in your workspace. This is due to the way Visual Studio manages the Virtual Directories behind Web Site Projects.

Click to Read More

My colleagues reported indeed some troubles when working with Visual Studio 2010 on Visual Studio Solutions containing Web Sites (not Web Applications) branched, e.g., from an existing TFS folder $/TeamProject/Main/Website onto a new branch $/TeamProject/Dev/WebSite (They still have indeed a few such Web Site Projects. Those cannot be upgraded into Web Applications as they use a framework that relies on various typical features of web sites, not supported by web applications. In addition, note that on the development workstations, the web sites are hosted in IIS due to some prerequisites of that framework, a.o. some limitation on the host header name and port).

Assume now that $/TeamProject is mapped withing a local workspace on C:\TFS\TeamProject, that there is no other mapping in this workspace and that one checks-in a new Web Site created in C:\TFS\TeamProject\Dev\WebSite. By default, the resulting server items will be located in  $/TeamProject/Dev/WebSite. And as you should know, a virtual directory named "WebSite" will have been created in IIS by Visual Studio and mapped on C:\TFS\TeamProject\Dev\WebSite behind the scene - mapping which is saved in the Visual Studio suo file).

Next, assume that one does a reverse integration of the Dev branch on the Main branch, that one checks-in the pending changes and that one opens next the Visual Studio Solution located in C:/TFS/TeamProject/Main (opening de facto also the web site)

Using Web Application Projects instead of a Web Site Projects, Visual Studio would alert the user that a Virtual Directory already exists with the same name but with another physical path (C:/TFS/TeamProject/Dev/WebSite in this case). And the user would be prompted to possibly redefine this Virtual Directory with the new location (i.e.: with C:/TFS/TeamProject/Main/WebSite). If the user refuses, the Web Application won't be loaded in Visual Studio. If he agrees, the Virtual Directory is remapped on the new location.

But with Web Site Projects, it's slightly different.... Visual Studio prompts the user to reuse the Virtual Directory. If the user refuses, a new Virtual Directory with the same name but suffixed with "_1" is created and mapped on the new physical path (opening again the web site from yet another physical location would results in suffixes "_2", "_3", etc...). This new name is unfortunately an issue for my colleagues, if they want to run the web site, again due to some constraints of the framework in use.

Instead, if the user accepts to reuse the Virtual Directory (expecting a behavior similar to the one experienced with Web Application Projects), Visual Studio will not redefine the physical location of the Virtual Directory; it will create new mappings in the workspace to get the sources from TFS in the physical location currently defined for the existing Virtual Directory. I.e.: the definition of the workspace will be like:

  • $/TeamProject                          ==>  C:/TFS/TeamProject
  • $/TeamProject/Main/WebSite ==>  C:/TFS/TeamProject/Dev/WebSite
And the Virtual Directory "WebSite" will be kept mapped on the physical location C:/TFS/TeamProject/Dev/WebSite.

Guess what if the user reopens later the solution in C:/TFS/TeamProject/Dev to implement new features on the web site in the Dev branch ? He will actually check-in his changes under the branch $/TeamProject/Main/

Upgrade to Web Applications is not an option at all - it was already investigated years ago and the cost was to high. But I could possibly investigate the use of the Visual Studio Development Web Server instead of IIS, although it is a prerequisite for the framework used in those web sites projects.

As a temporary solution, I suggest all users to delete any existing Virtual Directory before opening a Solution containing Web Sites Projects. If they have already reused an existing Virtual Directory, I suggest them to clean the messy mappings in their workspace and delete next the existing Virtual Directory. If they have a Solution working with a Virtual Directory suffixed with _1, I suggest them to delete their .suo file (otherwise Visual Studio will always recreate a Virtual Directory with that name when opening the Web Site Projects) and delete that Virtual Directory.

Notice: in some case (if not deleting/recreating correctly the Virtual Directory and the suo), you could have Visual Studio Solution files opened from various branches referencing the same Virtual Directory, obviously mapped on only one physical path, but without extra mappings in the workspace... And Visual Studio won't prompt you to use the existing Virtual directory when opening a solution. In such a case, delete the suo file of that solution.

TFS MSSCCI, TFS and branches can mess up your workspace...

At work, some colleagues are developing a standalone application hosted within the Visual Studio Isolated Shell. This application makes use of the DSM extension for Visual Studio to generate source code based on diagrams, source code which should be stored within TFS. Unfortunately, Team Explorer does not integrate with the Visual Studio Isolated Shell :(

So, they use MSSCCI as a solution to access TFS. But they recently noticed that this solution was messing up their workspace when working in multiple branches.

Click to Read More

TFS can be accessed from the Visual Studio Isolated Shell using the MSSCCI provider for Team Foundation (<= here the link for the 32bits/VS 2010 version).

My colleagues reported however some troubles when working on Visual Studio Solutions branched, e.g., from an existing TFS folder $/TeamProject/Main onto a new branch $/TeamProject/Dev.

Assume that $/TeamProject is mapped in a local workspace on C:\TFS\TeamProject, that there is no other mapping in this workspace and that one checks-in a new Visual Studio Solution created in C:\TFS\TeamProject\Dev (with one sub-folder per included Visual Studio Project). By default, the resulting server items will be located in  $/TeamProject/Dev with all projects' sub-folders created "recursively" bellow.

Next, assume that one does a reverse integration of the Dev branch on the Main branch, that one checks-in the pending changes and that one opens next the Visual Studio Solution located in C:/TFS/TeamProject/Main.

It appears that, behind the scene, Visual Studio with MSSCCI will create new workspace mappings between $/TeamProject/Main/xxx and C:/TFS/TeamProject/Dev/xxx. Any "Get Latest" made on the Main folder in TFS will update the local Dev subfolders! And when one will later open the Visual Studio Solution in this local Dev folder, expecting to work on the Dev branch, one will actually be working on the Main branch ;)

The reason is that the Visual Studio Isolated Shell with MSSCCI is using absolute paths in the Visual Studio Solution Files as references to included Visual Studio Project files. Visual Studio with Team Explorer is using relative paths instead. And when one opens a Visual Studio Solution Files containing absolute paths, mappings are created in the workspace, between the "server" items and those local "absolute paths". I.e.: the definition of the  workspace will be like:

  • $/TeamProject                          ==>  C:/TFS/TeamProject
  • $/TeamProject/Main/Project1   ==>  C:/TFS/TeamProject/Dev/Project1
  • $/TeamProject/Main/Project2   ==>  C:/TFS/TeamProject/Dev/Project2

If you ignore that absolute paths are used in your Visual Studio Solution file and if you don't pay attention to the server path of your pending changes, you will really be confused when your colleagues will complain that you didn't check-in your new features in the right branch or when a Gated Build will start on the Main branch when you check-in your changes :D