Why are my .csproj files getting messed up after a git rebase?

Mark Melville picture Mark Melville · Nov 20, 2012 · Viewed 7k times · Source

In a .NET C# project which uses GIT for source control, I keep getting malformed csproj files after rebasing to get the most recently commited code. This is my process:

  1. commit my code
  2. build and run tests
  3. rebase to "get latest"
  4. curse the heavens, as the csproj file is screwed up... AGAIN

Here's the output on the rebase:

D:\GitHub\AwesomeProject>git rebase master
First, rewinding head to replay your work on top of it...
Applying: added getstatus call
Using index info to reconstruct a base tree...
M       Host/Host.csproj
M       Host/packages.config
M       Trees/Trees.csproj
M       Trees/packages.config
M       UnitTests/UnitTests.csproj
<stdin>:1229: trailing whitespace.
  <!-- To modify your build process, add your task inside one of the targets bel
ow and uncomment it.
warning: 1 line adds whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging UnitTests/UnitTests.csproj
Auto-merging Trees/packages.config
CONFLICT (content): Merge conflict in Trees/packages.config
Auto-merging Trees/Trees.csproj
Auto-merging Host/packages.config
CONFLICT (content): Merge conflict in Host/packages.config
Auto-merging Host/Host.csproj
Failed to merge in the changes.
Patch failed at 0001 added getstatus call

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".

There are conflicts, but as you can see it auto-merged the csproj files, and it did it incorrectly!! The XML of the csprojfile is not valid and the project doesn't load. Here's a stripped down verstion of what it looks like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ... most of one version the project file
  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ... most of the other version the project file
  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
</Project>

Why is this happening? And how can I improve my process to deal with it?

Answer

dontangg picture dontangg · Nov 20, 2012

You may want to use a .gitattributes file to use a slightly different merge driver. I have found that this has helped with mine:

*.csproj -text merge=union
*.sln -text merge=union

You can read more about it here to see if there are options you like better.

You can also tell git to take a little longer thinking about its merges with the patience option like this: (read more here)

git rebase -s recursive -X patience

The only other thing that I can think of is to make sure that you pull code often so that the merges git has to do are smaller.

FYI, if you want you can do a rebase on the same line at the same time that you do a pull like this: (and you can still pass in the recursive and patience options the same)

git pull --rebase origin master