How do you handle VS.net sln and proj files in source control? - visual-studio

I hope this qualifies as programming related since it involves how to structure a project.
Because I've always used the web site model with VS.net I never had solution and project files and putting everything into source control worked great. I knew that everything I had in my web site directory was all I needed for the web site.
Now I'm using asp.net MVC and it only has a project model so now I have these solution and project files. If I work on it alone it's fine but once other people start to add/delete files from the project our solution file gets messed up and people end up having to grab the latest solution file, see what got changed and then add back/remove their files and check in the solution file again. It's become sort of a problem because sometimes people don't realize the solution file was changed, they make other changes and then when they check in everything other people do an update on their files they find that their files are gone from the project (although still physically on disk).
Is this normal? Is there a way to structure a project so that we don't need to check in solution and project files?

Your developers are not using TFS correctly. You should have multiple check-outs turned on, and everyone needs to be careful to merge their changes correctly when checking in. TFS will prompt you to do this, and accepting the defaults is nearly always the right thing to do.
It's not uncommon to have one or two developers who never get it, and you might have to help them now and then. But every programmer who works on a team needs to learn how to use source control tools correctly. If they can't manage that, they shouldn't be writing software.
[edit] It occurs to me that you might run into these problems if you check in the *.sln file directly, rather than choosing to "Add Solution to Source Control".

I don't think it's normal - what are you using for source control? It sounds like developers aren't respecting changes that others a making - checking in without merging first.
I know that early on in a project, when lots of files are being added & deleted, it can be a problem to keep up - you need to check out the project file, add your files, then check in the new file & project so other developers can also update it. You'll probably have multiple project files in a solution - perhaps one interim solution would be to have one "holding" project for each developer, then clean them up periodically - though these types of temporary fixes do have a tendency to become permanent.
I don't know of a way to set up a project file that's not in source control, though I suppose you could create a script that would generate them.
Having been through this, the key is respect & good communication between the developers.

This tends to happen with TFS multiple check outs. It can be hard to grasp coming from VSS to TFS as VSS allowed one person to check a file out at one time. Auto-merge should work most of the time for you but a couple of rules should ease the pain:
Check in early and often (if you add remove or rename a file check it in straight away even if it is a blank holder)
Before you check in do a get latest, this will ask you to resolve conflicts locally
Try to get continuous integration set up so that developers always know the state of the buidl and whether it is OK to check in\out.
We had a bit fo pain at the start of our current project but it soon settled down when we followed the rules above.

Personally, I think making changes to project and solution files requires discipline and clear (well understood) rules throughout your development team. These files (.sln, .*proj) are the bottlenecks of your project, and any errors or inconsistencies can cost you in team downtime. Changes need to be well thought out, planned and then executed.
They must be secured by source control (which you're already using, excellent) and your team members should work on the basis of only making the changes they need, and not leaving project or solution files checked out for an extended period.
If you are allowing multiple (shared) checkouts, this could become problematic in terms of overwriting another user's changes. Depending on your source control mechanism, people may be required to manually merge changes. Personally, I'd ask people to negotiate their project/solution changes with each other over merging (this can't always be achieved).
A third option if you are using TFS is the shelve feature. If someone needs to make changes locally, they can shelve the changes and merge later.
Lastly, another strategy is to try to architect your solution to be as modularized as possible - so people are distributed, working on separate projects and do not (ideally) have to overlap on too many common areas.

I'm not sure if you are using TFS, as people have mentioned, but if you are (or if you are using source control with similar capabilities) you can set it such that sln and csproj files are exclusive lockouts and are not able to be merged.
We have done this with quite large teams and while it causes some initial issues as people get used to it in the long run it has resolved many issues that were previously causing problems. Essentially you trade longer term merge issues/complexity for short term compile/checkin issues which we have found to be a good trade off.
Once you have set it to forced exclusive checkout and no merge you then get your dev teams used to the fact they should keep locks on the sln and proj files for as shorter time as possible.

Always check them in.
Always check out latest (merge if possible), make sure your change is there, before checking in a new version.
If your source control doesn't require a special action to check in from an old version, GET A DIFFERENT SOURCE CONTROL.

Related

Please settle a check out and lock vs update and merge version control debate

I've used source controls for a few years (if you count the Source Safe years), but am by no means an expert. We currently are using an older version of Sourcegear Vault. Our team currently uses a check out and lock model. I would rather switch to a update and merge model, but need to convince the other developers.
The reason the developers (not me) set up to work as check out and lock was due to renegade files. Our company works with a consulting firm to do much of our development work. Some years ago, long before my time here, they had the source control set up for update and merge. The consultants went to check in, but encountered a merge error. They then chose to work in a disconnected mode for months. When it was finally time to test the project, bugs galore appeared and it was discovered that the code bases were dramatically different. Weeks of work ended up having to be redone. So they went to check out and lock as the solution.
I don't like check out and lock, because it makes it very difficult for 2 or more people to work in the same project at the same time. Whenever you add a new file of any type or change a file's name, source control checks out the .csproj file. That prevents any other developers from adding/renaming files.
I considered making just the .csproj file as mergable, but the Sourcegear site says that this is a bad idea, because csproj is IDE auto-generated and that you cannot guarantee that two different VS generated files will produce the same code.
My friend (the other developer) tells me that the solution is to immediately check in your project. To me, the problem with this is that I may have a local copy that won't build and it could take time to get a build. It could be hours before I get the build working, which means that during that time, no one else would be able to create and rename files.
I counter that the correct solution is to switch to a mergable model. My answer to the "renegade files" issue is that it was an issue of poor programmer discipline and that you shouldn't use a weaker programmer choice as a fix for poor discipline; instead you should take action to fix the lack of programmer discipline.
So who's right? Is check in - check out a legitimate answer to the renegade file issue? Or does the .csproj issue far too big of a hassle for multiple developers? Or is Sourcegear wrong and that it should be ok to set the csproj file to update and merge?
The problem with update and merge that you guys ran into was rooted in a lack of communication between your group and the consulting group, and a lack of communication from the consulting group to your group as to what the problem was, and not necessarily a problem with the version control method itself. Ideally, the communication problem would need to be resolved first.
I think your technical analysis of the differences between the two version control methodologies is sound, and I agree that update/merge is better. But I think the real problem is in the communication to the people in your group(s), and how that becomes apparent in the use of version control, and whether the people in the groups are onboard/comfortable with the version control process you've selected. Note that as I say this, my own group at work is struggling through the exact same thing, only with Agile/SCRUM instead of VC. It's painful, it's annoying, it's frustrating, but the trick (I think) is in identifying the root problem and fixing it.
I think the solution here is in making sure that (whatever VC method is chosen) is communicated well to everyone, and that's the complicated part - you have to get not just your team on board with a particular VC technique, but also the consulting team. If someone on the consulting team isn't sure of how to perform a merge operation, well, try to train them. The key is to keep the communication open and clear so that problems can be resolved when they appear.
Use a proper source control system (svn, mercurial, git, ...)
If you are going to do a lot of branching, don't use anything less recent than svn 1.6. I'm guessing mercurial/git would be an even better solution, but I don't have too much hands-on-experience using those yet.
If people constantly are working on the same parts of the system, consider the system design. It indicates that each unit has too much responsibility.
Never, ever accept people to offline for more than a day or so. Exceptions to this rule should be extremely rare.
Talk to each other. Let the other developers know what your are working on.
Personally I would avoid having project files in my repository. But then again, I would never ever lock developers to one tool. Instead I would use a build system that generated project files/makefiles/whatever (CMake is my flavor for doing this).
EDIT: I think locking files is fixing the symptoms, not the disease. You will end up having developers doing nothing if this becomes a habit.
I have worked on successful projects with teams of 40+ developers using the update-and-merge model. The thing that makes this method work is frequent merges: the independent workers are continuously updating (merging down) changes from the repository, and everyone is frequently merging up their changes (as soon as they pass basic tests).
Merging frequently tends to mean that each merge is small, which helps a lot. Testing frequently, both on individual codebases and nightly checkouts from the repository, helps hugely.
We are using subversion with no check-in/check-out restrictions on any files in a highly parallel environment. I agree that the renegade files issue is a matter of discipline. Not using merge doesn't solve the underlying problem, what's preventing the developer from copying their own "fixed" copy of code over other people's updates?
Merge is a pita, but that can be minimized by checking in and updating your local copy early and often. I agree with you regarding breaking checkins, they are to be avoided. Updating your local copy with checked in changes on the other hand will force you to merge your changes in properly so that when you finally check-in things go smoothly.
With regards to .csproj files. They are just text, they are indeed mergeable if you spend the time to figure out how the file is structured, there are internal references that need to be maintained.
I don't believe any files that are required to build a project should be excluded from version control. How can you reliably rebuild or trace changes if portions of the project aren't recorded?
I am the development manager of a small company, only 3 programmers.
The projects we work on sometimes take weeks and we employ the big bang, shock and awe implementation style. This means that we have lots of database changes and program changes that have to work perfectly on the night that we implement. We checkout a program, change it and set it aside because implementing it before everything else will make 20 other things blow up. I am for check out and lock. Otherwise, another person might change a few things not realizing that program has had massive changes already. And the merge only helps if you haven't made database changes or changes to other systems not under source control. (Microsoft CRM, basically any packaged software that is extensible through configuration)
IMO, project files such as .csproj should not be part of the versioning system, since they aren't source really.
They also almost certainly are not mergeable.

Visual Studio, svn and merging .csproj and .sln files

Anyone had any success getting SVN to merge Visual Studio project (.csproj) or solution (.sln) files that have been edited by two users? Example
User A checks out project
User B checks out same project
User A adds a file
User A commits changes
User B adds a file
User B commits changes
Seems to me that at step (6), svn, Tortoise, Ankh or whatever should detect a conflict and either merge the two project files automatically or, more likely, prompt User B to resolve the conflict. Currently, we're seeing changes made by User A obliterated when User B checks in, resulting in bad builds, deploys, etc missing features that had been added before the last checkin.
Since the project files are XML, why is this an issue? Am I missing something here? I've searched the archives here and googled to I can't google no more, but haven't come up with a good solution.
How do you think you trick SVN into performing step #6? It seems you misunderstood what goes wrong. SVN will never ever commit from a working copy that's not up to date, so step #6 won't work without user B previously updating and merging user A's changes. Honestly. Try it.
I guess what happens instead is this:
A checks out project.
B checks out same project.
A adds a file.
A commits changes.
B adds a file, but forgets to save the project/solution.
B tries to commit changes and gets a message he should update first.
B updates.
B switches back to VS. VS tells him the project/solution changed on disk and asks whether he wants to a) reload from disk and lose his changes b) override the version on disk.
B doesn't understand, doesn't try to understand, considers his changes valuable, and picks b), overriding the changes on disk.
B still doesn't try to understand and thus does not diff the version he has on disk with the last committed one and thus misses that he overrode A's changes.
B Checks in, overriding A's changes.
I've seen this happening once in a while, usually with a user B who does not really understand SVN's (or CVS', FTM) workflow.
So here's a few hints:
Don't update unless you have saved everything ("File"->"Save All"; for me, that's Ctrl+Shift+S). In case you have made that mistake and you're stuck, do override the changes on disk and then merge the lost changes manually. (It might also work to update the project/solution file back to version N-1, and then to HEAD again, in order to have SVN perform the merge.)
Don't commit without checking which files you changed and having a quick look at the diffs to see whether the changes are what you expect.
Commit early, commit often. The more developers work on the same code base, the more likely you get conflicts. The longer you change your working copy without updating, the more likely you get conflicts. Since the number of developers usually is out of your hands, the update frequency is the one thing you can use to reduce the probability of conflicts.
I second sbi's answer. One possible solution is to always update from within Visual Studio, at least if you use VisualSVN (I'm not sure how AnkhSVN copes with this situation).
VisualSVN will block visual studio during the update operation, and make sure any changed projects are automatically reloaded, so users can not ignore the external changes.
A rather radical but efficient solution is to use a tool to generate those solution files from a meta-definition and then putting only the meta-definition under source control, not Visual Studio project files (which are a nightmare to merge).
In my team we use MPC to do this. We have:
a bunch of .mpc files for project descriptions,
a .mwc file for workspace / solution description,
a small .cmd to generate Visual Studio files.
Since they are all hand-edited text files, we no longer have problems with Visual Studio mixing up everything.
The drawbacks are an extra-tool and the need to regenerate the solution files when files are added or removed but there are some additional benefits too:
project configurations are centralized: for instance, changing a compilation flag is done in a single place instead of on a per-project basis,
this can accomodate multiple build systems (we currently use Visual 2003 and 2005 but this also works with gcc and others).
From my experience, althgough setting up the tool can be a bit painful (but it all depends on the size and complexity of your project), this is clearly worth it.
Note that MPC isn't the only tool for this purpose. Others exist, such as CMake.
You can also try to reduce conflicts by ensuring that your project files don't list every individual file inside the project. This will avoid the project file from being changed in first place when a user adds a file.
You're free to use wildcards inside a project file: see MSDN
Example:
<ItemGroup>
<Compile Include="Src\**\*.cs" />
[...]
</ItemGroup>
It is sad that Visual Studio doesn't encourage this kind of project setup and instead opts for listing individual files.
This is very tedious and tiresome so you just have to plow through it. You will sometimes keep the local working copy since it has all of your custom projects added. However, in other cases you will want to merge in all new items from the Base solution so you end up with everything from both solution files. For readability it is best to place all base product additions before customization additions.
Do not worry that the first portion of the GUID is identical for projects, but it is the last portion that will be unique.
Fissh

Shelving vs Workspaces in TFS

Currently I am working on a project that uses TFS as source control. I am in the middle of implementing a piece of functionality, but am blocked by work that needs to be done by outside resources. Since the functionality is not fully complete, I can't check in the changes without breaking the build. So instead of waiting a couple days while the blocking work is finished, I want to work on some defects.
To do this work in isolation from my other changes, I am working the defects in a second workspace I just created.
After using a second workspace to isolate my changes, a coworker asked me why I didn't just shelve my changes. After doing some reading on shelving, it looks like this is preferred solution to situations like mine. My question is what situations, if any, would you create multiple workspaces and what situations should you use shelving? There are some posts about shelving, but I don't see very much on the subject of workspaces.
By the way, I got the idea for creating a second workspace here.
A new branch would probably be the best way to go. But, to answer your question, one of the key differences between shelving and just using a differnet workspace is that when you shelve, you push your code back to TFS, so it is backed up. Whatever is in your workspace is just what you have on your machine -- if you lose it, it's gone.
We use branching a lot in my shop, and as a result, I haven't seen many uses for shelving.
However, I have found one case where it has been very useful to me:
I often bounce between 2 different development machines (one at the office, one at home, connected via VPN). If I am working on something, and I want to transfer it from home to work, or vice-versa, I often use shelving. I can shelve it from one machine and un-shelve it from the other. I do this when I am in the middle of a change, and checking in would break the build or otherwise interrupt other developers.
You are talking about two completely different concepts here. When you shelve code, you are saving it to TFS, but not checking it in to any particular branch. Creating a different workspace just sets up a new local folder on your development machines and saves the files in your branch there. When you do a check-in, you still could have conflicts.
Why not create a new branch of your code. You can work on that branch and check in without stepping on anyone else's changes, because you are checking in to your own branch of the code. Then, when you have completed your changes, and others have completed their's on the main branch, you can merge your changes into the main branch.
Shelving is the ideal option. Shelving allows you to make changes en masse in TFS outside the regular build, and retrieve them later by name. Multiple workspaces is not a solution for what you're doing. Multiple workspaces are good if you're maintaining different versions of a product and need to work on them, e.g. let's say you have a 4.0 and a 5.0 product and need to apply a security fix to both versions. Shelving is great when you want to make changes but not commit them immediately.

How do you manage .vcproj files in source control which are changed by multiple developers?

We use Subversion as our source control system and store the VisualStudio project files (vcproj) in the source control system as is normal I think. With Subversion we don't use any form of file locking, so if two developers are working on the same project at the same time and both add files to the project, or change settings, the second one to commit has to merge the changes.
How do you merge these changes?
The vcproj files are just text files so it is possible to edit them by hand but they are not very amenable to hand editing, especially by junior developers.
The ways I can think of are
Get the latest version from svn and re-add all local changes manually
Edit the file by hand to resolve any conflicts from an automatic merge
Implement some form of locking scheme to prevent simultaneous changes
Have an agreement between developers so they do not make simultaneous changes
Currently we are using the first option of re-adding all changes manually but this is time consuming and I was wondering if there is a better way.
With source files the automatic merge feature works most of the time and we don't get many conflicts.
I've found that option 2 (edit the files by hand) generally works fairly well, as long as you're using a good diff tool (I use WinMerge). The main problem I've run into is that Visual Studio will sometimes reorder the file. But, if you have a good diff/merge tool then it should be able to differentiate between changed content and moved content. That can help a lot.
You might find Project: Merge or Tools for SLN file useful
This is a tough problem and I think a weakness in the Visual Studio architecture. The way we found round it was to not have the proj files in source control at all and to have a build script that handled the configuration settings.
The alternative was very messy and we could not guarantee consistent builds or environments between developers. This led to a huge number of downstream integration problems and eventually we took the draconian step of removing the project files from source control.
The developers environments could still become misaligned but it showed up when they tried to build things themselves.
Using TFS here, but I don't think it makes a difference.
We also don't lock, and sometimes have to deal with merging project files. I've never found it to be that complex or much of an issue. Rarely do we ever experience issues that can't be merged automatically, and the manual merge process is pretty much trivial.
There's only one caveat to this: Check in often! If you make major changes to the project structure and don't check them in immediately those changes can start compounding the complexity of later merges. If I make a major change to the structure of a project, I usually give everybody a heads up. I'll ask them all to check in their current work, and then take care of the merge myself.
I found this recently: http://www.codeproject.com/KB/macros/vcproj_formatter.aspx
If you run this tool on a vcproj file and on a modified version of it then you can merge them together easily with your favorite text merge tool, and in addition the result is a more compact pretty vcproj file.
Options 1 and 2 are not mutually exclusive - if the developer is junior level, let them use option 1 (re-get the project file and re-do the changes) if that's more comfortable for them. For more senior developers, option 2 (merge using a merge tool) is perfectly fine.
I think this is a situation that currently has no magic bullet - sometimes merging is a pain.
We use a diff tool (WinMerge) to merge changes. The project files are (for the most part) really straight-forward XML. The key here, though, is that there never should be any surprises when merging, because good communication is part of the bed-rock of effective source control.
Simultaneous changes to the project are perfectly fine as long as people communicate.

Working on a Visual Studio Project with multiple users?

I just wonder what the best approach is to have multiple users work on a Project in Visual Studio 2005 Professional.
We got a Solution with multiple Class Libraries, but when everyone opens the solution, we keep getting the "X was modified, Reload/Discard?" prompt all the time. Just opening one project is an obvious alternative, but I find it harder to use as you can't just see some of the other classes in other projects that way.
Are there any Guidelines for Team Development with VS2005 Pro?
Edit: Thanks. The current environment is a bit limited in the sense there is only 1 PC with RDP Connection, but that will change in the future. Marking the first answer as Accepted, but they are all good :)
What you need is source control.
You should definitely not open the same files over the network on multiple machines. For one thing, Visual Studio has safeguards in place to prevent you from modifying certain files during a build, but it has none of that that will prevent others from modifying the same files over the network.
By setting up source control, each developer will have a separate copy of the files locally on his or her developer machine, and periodically communicate with the source control system to check in/commit changes. After that, other developers can ask for the latest updates when they're ready to retrieve them.
Use source control to keep a central repository of all your code. Then each user checks out their own copy of the source code and works locally. Then submits only the code that changed.
https://en.wikipedia.org/wiki/Version_control
A number of people have recommended using source control and I totally agree. However you also need do the following.
Exclude your personal options files from the repository (eg your .suo files)
Exclude your App.config files from the repository. - Not entirely but you need to have a Template.App.config. You commit that instead, and only copy your App.config into the Template.App.config when you make structural changes. That was each user has their own individual config for testing.
There are probably some other files worth excluding (obj directories and so forth) but thats all I can think of right now.
Peter
This might sound snide, but if you're opening up the solution from a shared location then you're doing something wrong. If that's the case then you should start using source control (something like Subversion) and have everyone check out a copy of the project to work on.
However if you're already using source control, then it might be a symptom of having the wrong things checked in. I find that you only need the sln, and the vcproj under source control.
Otherwise I don't know...
You should definitely, definitely be working with source control!
This will help stop the collisions that are occurring. Also, if you are making changes to the shared projects this often that it is a problem, then also ensure that all code is tested before getting checked in (otherwise they may bust someone else's build), but make sure they check in often (or time gained from not dealing with prompts will be lost in merging conflicts) :)

Resources