We're using Perforce and Visual Studio. Whenever we create a branch, some projects will not be bound to source control unless we use "Open from Source Control", but other projects work regardless. From my investigations, I know some of the things involved:
In our .csproj files, there are these settings:
Sometimes they are all set to "SAK", sometimes not. It seems things are more likely to work if these say "SAK".
In our .sln file, there are settings for many of the projects:
(The # is a number that identifies each project.) SccLocalPath is a path relative to the solution file. Often it is ".", sometimes it is the folder that the project is in, and sometimes it is ".." or "..\..", and it seems to be bad for it to point to a folder above the solution folder. The relativized one is a path from that folder to the project file. It will be missing entirely if SccLocalPath points to the project's folder. If the SccLocalPath has ".." in it, this path might include folder names that are not the same between branches, which I think causes problems.
So, to finally get to the specifics I'd like to know:
Added June 2012: I don't use Perforce any more, so I can't vouch for it, but have a look at KCD's answer below. Apparently there's a new P4 VS plugin under development. Hopefully it should clear up all this mess!
I would disagree with the claim that Perforce integration in Visual Studio is "terrible". Rather, I'd define it as "out of the box experience is less than optimal" :-). The following sections discuss my understanding of the integration and recommendations for project/solution setup.
If you're not interested in the details of how the source control integration works you can skip to the end of this answer where I summarize answers to Weeble's question.
Disclaimer: The following sections are just educated guesses based on my empirical experience, however I've used the technique over many years in many projects (each project having multiple experimental/trunk/maintenance/release branches, sometimes even multiple solution files, without issues). The disadvantage is that you have to manually update the project files - but the 2 minute investment is amortized over the lifetime of a project pretty nicely IMHO :-).
Visual Studio uses source control binding information from both solution file and each project file during the initial solution loading. This binding information is then stored in name.suo file (assuming we're using name.sln as solution) - note that suo files are marked with hidden flag so they won't be visible in file explorer (unless you override the "Hidden files and folders" option).
The easiest way to re-bind to source control provider if anything goes wrong is to delete the appropriate suo file and reopen solution. After suo file has been created, changes to <Scc*> elements have no effect.
If during the initial solution opening there is a discrepancy between the binding information stored in solution file and information stored in project file, Visual Studio will attempt to fix this (sometimes it will even prompt for your decision to choose whether the information in solution or the information in project should be used as a "master" to resolve the discrepancy):
Why is Visual Studio violating DRY (Don't Repeat Yourself) principle? I have no idea. I presume this has historic reasons and is tightly coupled to the needs of that nightmare called Visual Source Safe :-).
When adding either new or existing solutions/projects to Perforce, I always start by creating a blank solution (see the "Source-controlling a blank solution" section). I then add projects to this blank solution, one after another. The steps differ slightly based on whether the project being added already exists (see the "Source-controlling existing (unbound) projects" and "Source-controlling existing (bound) projects" sections) or I need to create a new one (see the "Source-controlling new projects" section).
To add a new blank solution to source control, do the following:
Open the name.sln file in your favourite editor (notepad, if you're really desperate :-) ) and add two new lines (SccProjectName0 and SccProvider0) - the blank solution file should now have a source control section as follows:
GlobalSection(SourceCodeControl) = preSolution SccNumberOfProjects = 1 SccLocalPath0 = . SccProjectName0 = Tutorial SccProvider0 = MSSCCI:Perforce\u0020SCM EndGlobalSection
The values should be chosen as follows:
You can now test the bindings:
If you're creating a brand-new project and would like to immediately start tracking it in a Perforce depot, follow these steps:
Manually edit the project file you just created using an editor of your choice (come on, notepad AGAIN? ;-) ). Add the following property elements into a PropertyGroup (any property group):
<PropertyGroup> ... <SccProjectName>Tutorial</SccProjectName> <SccLocalPath>..\..</SccLocalPath> <SccProvider>MSSCCI:Perforce SCM</SccProvider> ... </PropertyGroup>
The values should be chosen as follows:
Switch back to Visual Studio; it should automatically detect that the project file has been updated externally and offer to reload it (if not, unload and reload the project manually)
To verify that the newly added project is bound properly, you can follow these steps:
You can now verify source control status of the solution by using "File" -> "Source Control" -> "Change Source Control...":
One thing to note about this status screenshot is that when I selected the solution row, all the remaining rows were "selected" as well (blue highlight). This is because all those entries have the same "Server Binding" + "Local Binding" and thus share the same source-control-provider (P4) connection.
Also note that "Relative Path" for both projects has two levels, and are relative to the same "Local Binding" - the directory where solution file resides.
If you have existing projects that have not yet been used in any other Perforce solution, follow these steps to add them to Perforce (i.e. importing projects that have not been source-controlled before (Internet downloads etc.) or were using a different source control provider (Visual Source Safe, etc.).
Verification steps are exactly the same as in "Source-controlling new projects" section.
If you have projects that have already been bound to Perforce using the technique discussed here and you want to use them in a different solution (new branch, alternative solution reusing the project, etc) use the following steps:
I'm also including answers to your original questions:
What happens when you do "Change source control" and bind projects? How does Visual Studio decide what to put in the project and solution files?
This updates "Scc*" elements in a project file you're rebinding; the solution file is then updated as well so that it is in sync with the project file bindings
What happens when you do "Open from source control"?
Allows you to pick solution that you'd like to open. Afterwards all the projects included in the solution are automatically synced to head. I find this feature not very useful in Perforce world where you have to create a client anyway and the chances are you're syncing this client from a P4V/P4Win/P4 instead of relying on Visual Studio. This was kind-of useful in Visual Source Safe world where there was no concept of views and you were defining where a repository goes on checkout time.
What's this "connection" folder that SccLocalPath and SccProjectFilePathRelativizedFromConnection refer to? How does Visual Studio/Perforce pick it?
This is Visual Studio's bookkeeping. It is determined based on bindings in each project file (I guess in theory if a project file loses binding information for some reason, it could be reconstructed from the solution information...)
Is there some recommended way to make the source control bindings continue to work even when you create a new branch of the solution?
I hope the sections above give you some idea of a way that is working very well for me :-).
Milan's post is well-researched and well-written, but its length demonstrates beyond a shadow of a doubt that the P4SCC model is broken. Storing source control binding info inside the project & solution files is ridiculous. Enforcing (via sccprojectname) that a project be part of only one solution is equally ridiculous.
Additionally, P4SCC has a tremendous performance cost in a large solution, as it retrieves info from source control for each file at startup, and maintains that state in memory throughout the development session. It creates extra cruft in the form of information-free .vsscc & vssscc files to support some SCC feature that (AFAICT) Perforce does not use.
The ideal Perforce integration looks like:
We have moved completely away from P4SCC and its bizarre requirements and burdens. Instead we use NiftyPerforce. There are some bugs, but we find working around these bugs to be much less frustrating than working around the design defects in the Perforce<->VSSCC model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With