How To: Rename, Move, and Delete Source-Controlled Items in VS.NET

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.