Git + Windows + Visual Studio Merge Conflicts Caused by Line Ending Issues between branches
I’m having a difficult time trying to properly merge to branches. The branches seem to have line ending issues because when I open up the conflict window in Visual Studio its showing 0 conflicts and 0 differences between numerous files.
I’ve added a gitattributes file on both branches that looks and performed a repository refresh on both repositories.
When I refreshed both repositories there were no changes to commit, even though the instructions stated there would be changes to commit (essentially the changes being from the EOL conversions).
Here is my gitattributes
# Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain
I’ve also checked and my global core.autocrlf is equal to true (since all our devs are using Visual Studio on Windows)
The problem is, as I continue to do the above in hopes of fixing and normalizing these line branches across the two branches I end up with even MORE conflicts than previously – all due to line ends:
.git/config file (not including branch refs)
[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true symlinks = false ignorecase = true hideDotFiles = dotGitOnly autocrlf = true [merge] renormalize = true
I’m at my wits end, going through countless SO questions/answers – googling, to no avail – my conflict count continues to rise.
Also note: I’m using GIT on TFS – not sure if this changes things.
I’ve copied the said “conflicting” two files out from Visual Studio, each into their own Notepad++ windows with “show symbols -> show end of line” turned on – then I compared both “conflicting” files and as you can see there is NO difference in the line endings (both files contain the exact same CR/LF’s as shown in the image below) – so i’m guessing that VS is doing its EOL conversion or something? OR when I copy it out into Notepad++ its doing some sort of EOL conversion? Not sure if this helps at all.
I am running Visual Studio 2015 Update 3
I’ve added this handy End of Line Visual Studio Extension that shows the files EOL characters so I can see all the EOL characters right in the merge / diff screen and it appears they match exactly between the files.
OK – so I think i may be on to something here… I did a merge, then opened a conflicting file and this is what i found… the branch i’m merging FROM is using CRLF’s, the branching i’m merging INTO is using LF’s – so it does appear to be and EOL issue. I’m not sure how I can bulk fix this though? I though my initial repository refreshes I listed above would do this, apparently not.
Here is master (merging into master NOTE: this file is CRLF BEFORE merging, upon merging the CRLFs must be being converted to LF):
Here is what i’m merging from:
2 Solutions collect form web for “Git + Windows + Visual Studio Merge Conflicts Caused by Line Ending Issues between branches”
To be more consistent and be able to specify the line ending for different files by the extension, you can use .gitattributes file. The file is committed to the repository and will override the developers setting. The .gitattributes file should be created in the root of the repository and committed into the repo like any other file.
# Set behaviour for all files, in case developers don't have core.autocrlf set. * text=auto # Explicitly declare text files we want to always be normalized and converted to native line endings on checkout. *.txt text # Declare files that will always have CRLF line endings on checkout. *.sln text eol=crlf # Denote all files that are truly binary and should not be modified. *.zip binary
If you are using core.autocrlf = true, then in repo (TFS) all files are stored with LF, while on checkout GIT converts them to CRLF. The problem I’ve noticed with auto is according to documentation
“When the file has been committed with CRLF, no conversion is done.”
So basically if you have some files in repository commited with CRLF, because conversion wasn’t performed, in other branch you have normalized line endings (LF), then you receive conflicts uppon merge. It’s hard to see it because when you checkout, LF are replaced with CRLF and there seems to be no changes.
My approach is using CRLF as eol instead of auto, hoping that it will always replace CRLF -> LF on commit and LF -> CRLF on checkout.
*.cs text eol=crlf *.xaml text eol=crlf *.csproj text eol=crlf *.sln text eol=crlf
So to solve your issue you have to change on server line endings from CRLF to LF.
For me this command worked .gitattributes was modified and commited (even if I cannot explain it, but I got all the files with CRLF changed to LF on repository)
git rm --cached -rf . git diff --cached --name-only -z | xargs -n 50 -0 git add -f
And another thing, after changing .gitattributes you have to checkout your files again, I’m using this commands for it:
git rm -rf --cached . git reset --hard HEAD