Organize project XML files to reduce 3-way merge conflicts
If the project XML file contents were simply ordered, for instance alphabetically like a default file system view, it would drastically reduce the number of merge conflicts that edits cause.
Currently we see items added at the same spot in the file (so there is SOME order happening) with no relation other than time, causing a merge conflict that's completely avoidable. If an order was applied, it would make most 3-way merges automatic and/or a lot less work.
Kirill Osenkov commented
Oops, just read the comments and Josh Thompson is proposing exactly the same thing and has exactly the same tool :)
Kirill Osenkov commented
As somewhat of a workaround, you can try running a tool that sorts the projects alphabetically every once in a while. You can also run it before the merge on both source and destination to "normalize" both sides before diffing.
Careful though, the tool can sometimes change your formatting and whitespace (it doesn't preserve whitespace between XML attributes, this is a known problem in XLinq).
Josh Thompson commented
I just created a project on GitHub called CsProjArrange. I created it to fix the merging issues in my git repository. There are still some kinks which need to be ironed out, so I am open to some pull requests if you see anything that can be improved. It is located at https://github.com/miratechcorp/CsProjArrange
Fernando Auresco commented
I do work with TFS and I came to a point were is impossible to merge the solution files when working with my 5 person team. Most of the conflicts are because things added to the development branch csproj file are in different position than the main branch csproj file. Sorting alphabetically would really help here. I'll try to create an app to sort the csproj file myself. This is really a pain.
According to the comments here: http://haacked.com/archive/2014/04/16/csproj-merge-conflicts/ TFS has a semantic merge for these files so "it's not really a problem if you use TFS". Sounds like the perfect vested interest to avoid addressing this issue.
Stefan Sieber commented
Maybe it would also be fine if Visual Studio would default to a different kind of project setup - why for god's sake is it necessary to list all the files of a project? Wouldn't it be better if you include all source files inside certain directories?
That is how Eclipse handles it and until I switched to Visual Studio I couldn't even imagine that adding files to a project could cause merge conflicts. Visual Studio already supports using wildcards in the project files. All that would need to be done is adding support for it in the UI and probably also make it the default behaviour (adding whole directories instead of files).
Miroslav Bajtoš commented
Burton Rodman commented
+1M! Please apply this principal to all file types in Visual Studio system -- build templates being the WORST offender. I change 1 character in a build template and see 100s of lines changed in diffs. PLEASE FIX!
Tim Fish commented
For resx files, I created a command line app which my diff too uses to pre-process the files before comparing them. It loads the xml, sorts everything alphabetically and fixes formatting and works very well for merging. Before that it was a nightmare.
Philip Stears commented
+1 for Jason WIlliams' comment
"This applies to all project xml files, but in particular to SLN & RESX"
Indeed. There really should be a base ordering to components in resx, XML in anything generated by VS. In a multi-developer environment, a designer change that scrambles the designer contents makes the designer very difficult to use. Wastes hours every single merge.
Jason WIlliams commented
This applies to all project xml files, but in particular to SLN & RESX
In Solution files the XML includes a count of the number of active projects. If two people add a project, the count should be incremented twice, but as each developer has incremented it independently text-based merges just see the same change from both devs and consider it merged. This results in the file becoming corrupted by the merge as the value is now one less than it should be. As the number is simply a count of how many entries there are in one XML subtree, which would be trivial to calculate during loading, it is not something that should need to be serialised at all.
In resx files, simply loading and saving the resx completely re-orders the entire file meaning that they are impossible to merge - because of this we have to use exclusive checkouts on resx even when they only contain simple things like lists of user interface text messages.
Jason Stangroome commented
This should extend to all VS-generated files. Where the ordering of lines within the file (or part of the file) doesn't impact behaviour, a canonical order should always be used to improve the merging and differencing experiences.
Morgan Soley commented
Thanks for posting this. One of those daily development annoyances that everyone takes for granted but really shouldn't have to be dealt with.