In response to my recent post, What is a Source Control Binding?, reader Keith Hill writes,

"A bit OT but do you know why VS.NET SCCI can't handle renaming projects once they are checked into a SCM system (ClearCase) is what I am using)? (...) It sure would be nice if the VS.NET SCCI could just handle this for me."

Indeed, it would be nice if SCCI supported automatic renames. And just to be clear; renames are just one of a set of similar operations, which I’ll refer to as namespace changes in this post. Namespace changes include RENAMES, MOVES, and DELETES.

So why aren't namespace changes that we make to our projects and files in Visual Studio .NET pushed to the source control database and committed automatically? 

Short answer: the source control plug-in providers (Rational, SourceGear, Microsoft, Perforce, PVCS, etc) have not taken the time to provide this functionality and/or have not demanded that this functionality be facilitated by the addition of MSSCCI functions. Of course, namespace tracking of the sort that ensures that your file renames in VS.NET are pushed to the database version of that file is completely doable, even today. However, the projected cost of doing it right--of implementing an elegant namespace change-aware source control system for integration with Visual Studio .NET and other development environments (Dreamweaver jumps to mind)--appears to have deterred even the most deep-pocketed source control vendors.  The architecture isn’t exactly mind bending. The do-it-right approach involves some or all of the following elements. Namespace changes must be:

a)     Performed in a Transactional way (SCCI commits all namespace changes at one time; on check in, for instance);

b)     Reversible (for example, on loss of network connectivity or in response to an Undo Checkout operation);

c)     Tracked by the source control system using GUIDs that link a working copy of a file to its master copy in the database or;

d)     [Optionally] broadcast or propagated to all users' working copies of that project (msg, 'Hey, UserA just renamed a file you have checked out. What do you want to do?').

A truly transactional source control solution would be ideal. The ability to reverse, or roll back a namespace change (which would be close to ideal) would require the provider to either cache a complete copy of a solution or add some code to their systems that would preserve the history of name changes to a file until the parent project/solution is checked in or an undo checkout is requested. Again, I don’t think that any of the providers do this currently. MSSCCI uses actual file names to uniquely identify all source-controlled files rather than separate GUIDs. Changings this could allow a file that is renamed in one place (on the client) to be mapped to a file with another name (the as yet un-renamed file in the scc database). Finally, none of the SCC providers provide namespace change broadcasting or notification services. Again, I reserve the right to be mistaken.

A A halfway solution?

The Visual Studio .NET source control integration development team has considered it.  However, in lieu of a well-designed namespace change-aware system, the risks associated with renaming a project or file in the database, automatically, outweigh the potential advantages.

You might ask, “what are these risks associated with renaming projects?" To answer that question, consider the following hypothetical scenario:

S Simple Rename Scenario--Single User

Risk: unable to easily undo checkout of a solution containing a renamed file.

++Assumes that client file renames are immediately committed in the SCC database++

Bob renames a project from Peck.csproj to Hubble.csproj. Two files are changed in Bob's working folder: the solution file (telescope.sln) and Peck.csproj. The SCS system detects a namespace change (the rename) and automatically commits that one change to the database; Peck.csproj gets renamed to Hubble.csproj. The database version of telescope.sln is not updated, and thus, differs from Bob’s version of the solution file. Bob works on his project for a while and then decides--for whatever reason--to undo checkout for the entire solution. The telescope.sln file that he gets back from source control references the old project name, ‘Peck’. The source control system cannot find a project named 'Peck' on local disk (because neither local source control integration nor the MSSCCI provider remembers the rename to the project file, therefore none of them can undo this change) so it assumes that another user has added a new project to the solution. Consequently, the SCC provider attempts to get the “new” project and all of its files. But there isn’t a project 'Peck' in the SCC database because it has been renamed to Hubble. The Get operation fails and Bob ends up with a solution with a missing/unloaded project.

To fix this issue, Bob must:

1.      Check out the solution exclusively.

2.      Open the database and manually rename Hubble.csproj to Peck.csproj.

3.      Manually rename Hubble.csproj.vspscc to Peck.csproj.vspscc.

4.      Get the files locally, etc and then reload the projects into the solution.

In an ideal world, the best way to solve this problem would be to add some code to scci to preserve the history of name changes to a file until the parent project/solution is checked in or until an undo checkout occurs.

Basically, if we could remember that Peck was renamed to Hubble, after we get the old solution we could rename Hubble back to Peck. Tracking this kind of change is non trivial though. The SCCI code would have to remember changes like Peck->Hubble->Orbit->Peck->(delete)Peck, or Peck->Hubble->(delete) Hubble ->(add different) Peck, etc.

C Complex Rename Scenario (Multi-user)

Risk: Teammate’s changes cannot be merged into the main code line.

++Again, assumes that client file renames are immediately committed in the SCC database++

As in the previous scenario, Bob renames one of the projects in the telescope solution. The database version of the project file is changed from Peck.csproj to Hubble.csproj. While Bob is working on the (checked-out) source files, his co-worker Mike opens the telescope solution from source control for the first time in order to make a set of targeted bug fixes. Mike gets a version of telescope.sln that contains a reference to ‘Peck.csproj’, but in the source control database there is no such project. He ends up with a missing/unloaded project and a solution that cannot be built. Mike cannot build his enlistment and might not even be able to edit the files or to fix the bug (if the bug was in the Peck project’s project files).

Concurrently, John--a third team member--who had previously opened the telescope solution from source control and has all the files locally, attempts to Get the latest version of the solution from source control in order to incorporate any outstanding team changes into his working copy before building and checking in. However, since Peck.csproj has been renamed in the database, the SCC status for John's copy of project is ‘uncontrolled’ and the file appears as a 'pending add'.

John, who has added several files and has made major build configuration changes since checking out the solution, decides to add Peck.csproj to and check in his version of the solution. Consequently, Peck.csproj is added back to the SCC database.

Now, there are 2 project files in the database, Peck.csproj and Hubble.csproj.

A few minutes later Bob checks in his changes. The solution file now references the new project Hubble.csproj rather than Peck.csproj. Effectively, John's major changes (file additions/changed build configuration) are orphaned and will have to be, when somebody realizes that they're missing, re-integrated into the main codeline, manually and painfully.

S Summary

In the absence of reliable mechanisms for 1) rolling back and synchronizing previously committed namespace changes between a source control database and a local enlistment and; 2) disseminating namespace change notifications or commits to all project enlistees automatically, it is much safer to implicitly discourage renaming, moving, or deleting source-controlled files and projects than to complete such operations automatically and thereby enable serious scheduling setbacks in mainstream collaborative development scenarios.  Whew.  That was a mouthful.

I can only assume that the source control providers (VSS, ClearCase, PVCS, Vault, et al) are as responsible for the lack of transactionality in source control integration as SCCI in Visual Studio .NET. I speculate that the SCCI team has entertained some requests from our VSIP partners in this area sometime in the past and that somebody whose salary is much bigger than mine said, "Whoa. That sounds expensive. Let's punt."  Obviously, the second roadblock (lack of ability to 'push' namespace changes down to project enlistees) would be the sole responsibility of the source control provider.

To rename, move, or delete a source-controlled file or project in Visual Studio .NET 2002 or 2003

1.      Inform all project enlistees that you plan to make a namespace change to the project.

2.      Ask all project enlistees to check in the solution to which the file or project belongs.

3.      Rename, move, or delete the item in Visual Studio .NET.

4.      Check in your changes.

5.      Ask all project enlistees to synchronize their working copies of the solution with the database version.

For more information see Q305516.

++++++++++++++++++++++++++++

Ugh, This posting is provided "AS IS" with no warranties, and confers no rights. Microsoft kann für die Richtigkeit und Vollständigkeit der Inhalte in dieser Newsgroup keine Haftung übernehmen. Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningún derecho. Ce message est fourni en l’état, sans garantie d’aucune sorte, et ne vous confère aucun droit. Vous assumez tous les risques liés à son utilisation. Il presente posting viene fornito “così come é”, senza garanzie, e non conferisce alcun diritto.