Conflicts when merging csproj files

Original author: Phil Haack
  • Transfer


In the current version of GitHub for Windows, we made a small change that has a barely noticeable effect, which you probably already noticed. We changed the *.csprojdefault merge and similar file approach .
If you modify the .csprojfile in a branch and then merge it with another branch, then you may encounter more merge conflicts than you might have before.

Why?

Well, earlier we would use unionto merge *.csproj files.
git merge-filedocumentation describing this function:

Instead of leaving the conflict in the file, resolve the conflicts in favor of our (or their or both) side.

In general, when a conflict occurs, the system tries to solve this problem, trying to apply all the changes.
In principle, this is a compromise. This approach can be customized in the file .gitattributes, so if you really want to use this behavior for your repository, add the following:
*.csproj  merge=union

And now let me tell you why maybe you do not want to do this, and why we eventually changed this.

The merger turned into a disaster


Suppose we start with the following simplified foo.csprojfile in our branch mastertogether with a file .gitattributes:
DesignerMSBuild:CompileDesignerMSBuild:Compile


After creating this file, let's make sure that we commit it
git init .
git add -A
git commit -m "Initial commit of gittattributes and foo.csproj"


Then we create a branch ( git checkout -b branch) with the original name “branch” and insert the piece below in foo.csprojbetween AAA.csand DDD.cs.
DesignerMSBuild:Compile


For those who have a weak imagination, below is the result of what we commit to this thread.
DesignerMSBuild:CompileDesignerMSBuild:CompileDesignerMSBuild:Compile


Do not forget to commit this if you act in order.
git commit -a "Add BBB.cs element"


Now let's go back to the master branch
git checkout master


And add the following piece there:
DesignerMSBuild:Compile


As a result, the master branch should contain the following:
DesignerMSBuild:CompileDesignerMSBuild:CompileDesignerMSBuild:Compile


And all this is committed:
git commit -a "Add CCC.cs element"


Are you still here
Ok now let's merge our branch branchinto a branchmaster
git merge branch


As a result of using merge by union, we get the following:
DesignerMSBuild:CompileDesignerMSBuild:CompileDesignerMSBuild:Compile


Damn (yiuu), it turned out not quite what we wanted. Note that “BBB.cs” is embedded in “CCC.cs” and we no longer have a closing tag. It’s terrible to say the least.
In the absence of a file .gitattributesin the repository and using the standard merge approach, the standard merge command resulted in a merge conflict that needs to be fixed. In our understanding, this is better than a glaring mistake that will remain in your project.
DesignerMSBuild:Compile
<<<<<<< HEAD
    
=======
    
>>>>>>> branch
      DesignerMSBuild:CompileDesignerMSBuild:Compile


Obviously, in some perfect parallel universe, git would have placed the entire ccc element after the bbb element without gag and not bothering us about resolving these nasty merge conflicts. We do not live in this universe, but maybe ours can become a little more like an ideal one. I heard it cool.

What should be done in Visual Studio?


I recently asked Twitter subscribers to vote on a question asking a Visual Studio team to add support for file templates in project files . MSBuild already supports wildcard characters in .csproj files, but Visual Studio doesn’t work with them so far.

Reducing the torment in resolving merger conflicts is one of the main reasons to do so. If I can use the joker character to indicate the directory, I will not need to add entries *.csprojevery time I add a file to the project.

On the other hand, you can write a quality XML merge driver for Git, but this is quite a serious test, and my colleague Marcus Olssoncan confirm it. If it were simple, or even difficult but in moderation, it would have already been done. Curiously, if we limit this to the usual .csprojfile problem , can we say that although this is not a great, but good enough solution to control common merge conflicts? Maybe.

Even if we write this merge driver, it can solve the problem of only one specific version control system, which is only important for us. :trollface:

It has been suggested that if Visual Studio first sorts these items, then this may help partially solve the problem. This will help reduce minor conflicts arising from the fault of conditionally non-deterministic sorting of elements in Visual Studio. But this will not solve the merger problem as such. In the example I presented, each element retains sorting throughout the example. It turns out that every time when adjacent files are added in two different branches, you run the risk of getting a conflict. Which happens quite often.

Joker character support can almost completely solve this problem. Notice, I said almost . There will still be conflicts in this file from time to time, but this will happen very rarely.

ps
By the will of fate, I came across this article, I decided that it will also be interesting for you to know, I personally encounter this constantly.
This is my first translation, so please answer the question in the questionnaire, I would like to know whether to spend your / my time further or not.

Only registered users can participate in the survey. Please come in.

Do you like / Do you understand the translation?

  • 26.7% Yes 27
  • 40.5% OK 41
  • 16.8% Three with a minus 17
  • 8.9% Sit down, two 9
  • 6.9% No 7

Also popular now: